aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlantw44 <lantw44@gmail.com>2013-01-26 20:29:09 +0800
committerlantw44 <lantw44@gmail.com>2013-01-26 20:29:09 +0800
commitc41f897304100c89451e91acb0a47b3f07fc7b51 (patch)
tree474fb9045318b674cf01c70f087cb6efabbdf3a9
parente5ee20baf2abee4527a01193a30ea27a33ca1e31 (diff)
downloadsctjudge-c41f897304100c89451e91acb0a47b3f07fc7b51.tar.gz
sctjudge-c41f897304100c89451e91acb0a47b3f07fc7b51.tar.zst
sctjudge-c41f897304100c89451e91acb0a47b3f07fc7b51.zip
清除所有 pthread_cancel()
已使用 sem_timedwait 和 sem_post 取代所有以往需要 pthread_cancel 的地方
-rw-r--r--COPYING2
-rw-r--r--src/checktle.c29
-rw-r--r--src/disptime.c20
-rw-r--r--src/main.c6
-rw-r--r--src/mkchild.c13
-rw-r--r--src/sctcore.h2
6 files changed, 30 insertions, 42 deletions
diff --git a/COPYING b/COPYING
index b529e31..175bc9a 100644
--- a/COPYING
+++ b/COPYING
@@ -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(&timesleep, 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;
diff --git a/src/main.c b/src/main.c
index d46c4c3..eabf764 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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;