diff options
author | lantw44 <lantw44@gmail.com> | 2013-01-26 20:29:09 +0800 |
---|---|---|
committer | lantw44 <lantw44@gmail.com> | 2013-01-26 20:29:09 +0800 |
commit | c41f897304100c89451e91acb0a47b3f07fc7b51 (patch) | |
tree | 474fb9045318b674cf01c70f087cb6efabbdf3a9 | |
parent | e5ee20baf2abee4527a01193a30ea27a33ca1e31 (diff) | |
download | sctjudge-c41f897304100c89451e91acb0a47b3f07fc7b51.tar.gz sctjudge-c41f897304100c89451e91acb0a47b3f07fc7b51.tar.zst sctjudge-c41f897304100c89451e91acb0a47b3f07fc7b51.zip |
清除所有 pthread_cancel()
已使用 sem_timedwait 和 sem_post 取代所有以往需要 pthread_cancel 的地方
-rw-r--r-- | COPYING | 2 | ||||
-rw-r--r-- | src/checktle.c | 29 | ||||
-rw-r--r-- | src/disptime.c | 20 | ||||
-rw-r--r-- | src/main.c | 6 | ||||
-rw-r--r-- | src/mkchild.c | 13 | ||||
-rw-r--r-- | src/sctcore.h | 2 |
6 files changed, 30 insertions, 42 deletions
@@ -1,4 +1,4 @@ -Copyright (c) 2012, 藍挺瑋 +Copyright (c) 2012-2013, 藍挺瑋 All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/checktle.c b/src/checktle.c index 9aec3f7..461147b 100644 --- a/src/checktle.c +++ b/src/checktle.c @@ -17,24 +17,21 @@ volatile sig_atomic_t break_flag; static void break_handler(int signo){ break_flag = 1; + sem_post(&tlethr); } void* sctjudge_checktle(void* arg){ pid_t pidcopy; long long sleeptime = (long long)(*(int*)arg) * 1000000; struct sigaction break_catch; - struct timespec timelimit, timeinit, timecur, timetmp; + struct timespec timelimit, timeinit, timecur, timeexpire; const struct timespec nanslparg = {0, SCT_CHECKTLE_INTERVAL}; pthread_mutex_lock(&tkill_mx); tkill_yes = 1; pthread_mutex_unlock(&tkill_mx); - pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); - pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); - - sem_wait(&addthr); - pthread_testcancel(); + sem_wait(&tlethr); clock_gettime(CLOCK_REALTIME, &timeinit); #ifndef HAVE_CONF_CAP @@ -54,19 +51,13 @@ void* sctjudge_checktle(void* arg){ timelimit.tv_sec = timeinit.tv_sec + sleeptime / 1000000000; timelimit.tv_nsec = timeinit.tv_nsec + sleeptime % 1000000000; - pthread_testcancel(); - - for(clock_gettime(CLOCK_REALTIME, &timecur); - comparetimespec(&timecur, &timelimit) < 0 && !break_flag; - clock_gettime(CLOCK_REALTIME, &timecur)){ - difftimespec(&timecur, &timelimit, &timetmp); - if(comparetimespec(&timetmp, &nanslparg) > 0){ - nanosleep(&nanslparg, NULL); - }else{ - nanosleep(&timetmp, NULL); - } - pthread_testcancel(); - } + do{ + clock_gettime(CLOCK_REALTIME, &timecur); + timeexpire.tv_sec = timecur.tv_sec; + timeexpire.tv_nsec = timecur.tv_nsec + SCT_CHECKTLE_INTERVAL; + checktimespec(&timeexpire); + }while(comparetimespec(&timecur, &timelimit) < 0 && + sem_timedwait(&tlethr, &timeexpire)); if(!break_flag){ pthread_mutex_lock(&judge_tle_mx); diff --git a/src/disptime.c b/src/disptime.c index 9711b7c..deeee68 100644 --- a/src/disptime.c +++ b/src/disptime.c @@ -15,6 +15,7 @@ void* sctjudge_displaytime(void* arg){ struct timespec timeinit, timecur, timepast; struct timespec timesleep; + struct timespec timeexpire; timesleep.tv_sec = 0; timesleep.tv_nsec = (*(long*)arg); @@ -42,11 +43,7 @@ void* sctjudge_displaytime(void* arg){ tdisplay_yes = 1; pthread_mutex_unlock(&tdisplay_mx); - pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); - pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); - - sem_wait(&addthr); - pthread_testcancel(); + sem_wait(&dispthr); #ifndef HAVE_CONF_CAP enable_setuid(); @@ -65,10 +62,7 @@ void* sctjudge_displaytime(void* arg){ sprintf(statusfile, PROC_PATH"/%d/status", pidcopy); #endif - pthread_testcancel(); - - while(1){ - pthread_testcancel(); + do{ clock_gettime(CLOCK_REALTIME, &timecur); difftimespec(&timeinit, &timecur, &timepast); printf("\r%4ld.%03ld 秒", timepast.tv_sec, @@ -139,8 +133,12 @@ void* sctjudge_displaytime(void* arg){ firstrun = 0; #endif fflush(stdout); - nanosleep(×leep, NULL); - } + + clock_gettime(CLOCK_REALTIME, &timecur); + timeexpire.tv_sec = timecur.tv_sec + timesleep.tv_sec; + timeexpire.tv_nsec = timecur.tv_nsec + timesleep.tv_nsec; + checktimespec(&timeexpire); + }while(sem_timedwait(&dispthr, &timeexpire)); pthread_mutex_lock(&tdisplay_mx); tdisplay_yes = 0; @@ -418,7 +418,8 @@ int main(int argc, char* argv[]){ pthread_mutex_init(&tdisplay_mx, NULL); pthread_mutex_init(&judge_tle_mx, NULL); sem_init(&mcthr, 0, 0); - sem_init(&addthr, 0, 0); + sem_init(&tlethr, 0, 0); + sem_init(&dispthr, 0, 0); pthread_create(&tmain, &joistate, &sctjudge_makechild, (void*)&mcopt); if(!dryrun){ pthread_create(&tkill, &detstate, &sctjudge_checktle, @@ -439,7 +440,8 @@ int main(int argc, char* argv[]){ pthread_mutex_destroy(&tdisplay_mx); sem_destroy(&mcthr); - sem_destroy(&addthr); + sem_destroy(&tlethr); + sem_destroy(&dispthr); if(dryrun){ return SCTEXIT_SUCCESS; diff --git a/src/mkchild.c b/src/mkchild.c index fe2ee8c..3f754a7 100644 --- a/src/mkchild.c +++ b/src/mkchild.c @@ -72,7 +72,7 @@ pid_t pidchild; pthread_mutex_t pidmutex, tkill_mx, tdisplay_mx, judge_tle_mx; pthread_t tkill, tdisplay; char tkill_yes = 0, tdisplay_yes = 0, judge_tle = 0; -sem_t mcthr, addthr; +sem_t mcthr, tlethr, dispthr; static const char* childmsg_text[SCTCHILD_MSGMAX] = { "開啟輸入檔案", @@ -99,7 +99,7 @@ static void sctjudge_makechild_cleanup_p1(void){ if(tkill_yes){ tkill_yes = 0; pthread_mutex_unlock(&tkill_mx); - pthread_cancel(tkill); + sem_post(&tlethr); }else{ pthread_mutex_unlock(&tkill_mx); } @@ -108,14 +108,11 @@ static void sctjudge_makechild_cleanup_p1(void){ if(tdisplay_yes){ tdisplay_yes = 0; pthread_mutex_unlock(&tdisplay_mx); - pthread_cancel(tdisplay); + sem_post(&dispthr); }else{ pthread_mutex_unlock(&tdisplay_mx); } - /* 這基本上應該是可以去掉的,sem_wait() 也是 cancellation point */ - sem_post(&addthr); - sem_post(&addthr); } static void sctjudge_makechild_cleanup_p2(mcopt, oldperm, copiedexe) @@ -429,8 +426,8 @@ void* sctjudge_makechild(void* arg){ /* 現在我們確定受測程式已經在執行了,所以需要記錄一下時間 * 通知其他 thread */ - sem_post(&addthr); - sem_post(&addthr); + sem_post(&tlethr); + sem_post(&dispthr); /* 開始要 wait 了,莫名其妙 stop 的程式我最多只會送 * 5 次 SIGCONT 給你(避免進入無限迴圈) diff --git a/src/sctcore.h b/src/sctcore.h index 98bbda5..13c8783 100644 --- a/src/sctcore.h +++ b/src/sctcore.h @@ -21,7 +21,7 @@ extern char tkill_yes, tdisplay_yes; extern pthread_mutex_t tkill_mx, tdisplay_mx; /* 用來讓另外兩個 thread 卡住的 semaphore */ -extern sem_t mcthr, addthr; +extern sem_t mcthr, tlethr, dispthr; /* 判斷有無 TLE,此變數由 sctjudge_checktle 設定 */ extern char judge_tle; |