void testAlarmInsertionOfThreeEvents(void) { int* e2_arg = malloc(sizeof(int)); *e2_arg = test_e2_arg; alarm_insert(test_e2_timeout, assign_handler, e2_arg); int* e3_arg = malloc(sizeof(int)); *e3_arg = test_e3_arg; alarm_insert(test_e3_timeout, assign_handler, e3_arg); event_bin_t* head = alarm_queue->head; if(!assert_not_null(head)) return; uint16_t acc_value = 0; event_bin_t* bin1 = head->next; if(!assert_not_null(bin1)) return; if(!assert_equal_uint16(test_e2_timeout - acc_value, bin1->e.rank)) return; if(!assert_equal_ptr(assign_handler, bin1->e.handler)) return; if(!assert_equal_ptr(e2_arg, bin1->e.arg_ptr)) return; acc_value += bin1->e.rank; event_bin_t* bin2 = bin1->next; if(!assert_not_null(bin2)) return; if(!assert_equal_uint16(test_e1_timeout - acc_value, bin2->e.rank)) return; if(!assert_equal_ptr(assign_handler, bin2->e.handler)) return; acc_value += bin2->e.rank; event_bin_t* bin3 = bin2->next; if(!assert_not_null(bin3)) return; if(!assert_equal_uint16(test_e3_timeout - acc_value, bin3->e.rank)) return; if(!assert_equal_ptr(assign_handler, bin3->e.handler)) return; assert_equal_ptr(e3_arg, bin3->e.arg_ptr); }
void testFollowerOfHeadAfterInsertingOne(void) { int* e1_arg = malloc(sizeof(int)); *e1_arg = test_e1_arg; alarm_insert(test_e1_timeout, assign_handler, e1_arg); event_bin_t* head = alarm_queue->head; if(!assert_not_null(head)) return; event_bin_t* follow_head = head->next; if(!assert_not_null(follow_head)) return; if(!assert_equal_uint16(test_e1_timeout, follow_head->e.rank)) return; if(!assert_equal_ptr(assign_handler, follow_head->e.handler)) return; assert_equal_ptr(e1_arg, follow_head->e.arg_ptr); }
int main(int argc,char* argv[]) { int status; char line[128]; alarm_t* alarm; pthread_t thread; status=pthread_create(&thread,NULL,alarm_thread,NULL); if(status!=0) { err_abort(status,"Create alarm thread"); } while(1){ printf("Alarm> \n"); if(fgets(line,sizeof(line),stdin)==NULL) exit(0); if(strlen(line)<=1) continue; alarm=(alarm_t*)malloc(sizeof(alarm_t)); if(alarm==NULL) { errno_abort("Allocate alarm"); } if(sscanf(line,"%d %64[^\n]", &alarm->seconds,alarm->message)<2) { fprintf(stderr,"Bad command\n"); free(alarm); } else { status=pthread_mutex_lock(&alarm_mutex); if(status!=0) { err_abort(status,"Lock mutex"); } alarm->time=time(NULL)+alarm->seconds; alarm_insert(alarm); status=pthread_mutex_unlock(&alarm_mutex); if(status!=0) { err_abort(status,"Unlock mutex"); } } } return 0; }
void* alarm_thread(void* arg) { alarm_t* alarm; struct timespec cond_time; time_t now; int status,expired; status=pthread_mutex_lock(&alarm_mutex); if(status!=0) { err_abort(status,"Lock mutex"); } while(1) { current_alarm=0; while(alarm_list == NULL) { status=pthread_cond_wait(&alarm_cond,&alarm_mutex); if(status!=0) { err_abort(status,"Wait on cond"); } } alarm=alarm_list; alarm_list=alarm->link; now=time(NULL); expired=0; if(alarm->time > now) { #ifdef DEBUG printf("[waiting:%d(%d)\"%s\"]\n",alarm->time, alarm->time-time(NULL),alarm->message); #endif cond_time.tv_sec=alarm->time; cond_time.tv_nsec=0; current_alarm=alarm->time; while(current_alarm==alarm->time) { status=pthread_cond_timedwait( &alarm_cond,&alarm_mutex,&cond_time); if(status==ETIMEDOUT) { expired=1; break; } if(status!=0) { err_abort(status,"Cond timedwait"); } } if(!expired) { alarm_insert(alarm); } } else { expired=1; } if(expired) { printf("(%d) %s\n",alarm->seconds,alarm->message); free(alarm); } } }