79 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			79 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | #include <kinc/threads/event.h>
 | ||
|  | 
 | ||
|  | #include <assert.h>
 | ||
|  | #include <errno.h>
 | ||
|  | #include <sys/time.h>
 | ||
|  | 
 | ||
|  | void kinc_event_init(kinc_event_t *event, bool auto_reset) { | ||
|  | 	event->impl.auto_reset = auto_reset; | ||
|  | 	event->impl.set = false; | ||
|  | 
 | ||
|  | 	pthread_cond_init(&event->impl.event, NULL); | ||
|  | 
 | ||
|  | 	// pthread_mutexattr_t attr;
 | ||
|  | 	// pthread_mutexattr_init(&attr);
 | ||
|  | 	// pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
 | ||
|  | 	pthread_mutex_init(&event->impl.mutex, NULL); //&attr);
 | ||
|  | } | ||
|  | 
 | ||
|  | void kinc_event_destroy(kinc_event_t *event) { | ||
|  | 	pthread_cond_destroy(&event->impl.event); | ||
|  | 	pthread_mutex_destroy(&event->impl.mutex); | ||
|  | } | ||
|  | 
 | ||
|  | void kinc_event_signal(kinc_event_t *event) { | ||
|  | 	pthread_mutex_lock(&event->impl.mutex); | ||
|  | 	if (!event->impl.set) { | ||
|  | 		event->impl.set = true; | ||
|  | 		pthread_cond_signal(&event->impl.event); | ||
|  | 	} | ||
|  | 	pthread_mutex_unlock(&event->impl.mutex); | ||
|  | } | ||
|  | 
 | ||
|  | void kinc_event_wait(kinc_event_t *event) { | ||
|  | 	pthread_mutex_lock(&event->impl.mutex); | ||
|  | 	while (!event->impl.set) { | ||
|  | 		pthread_cond_wait(&event->impl.event, &event->impl.mutex); | ||
|  | 	} | ||
|  | 	if (event->impl.auto_reset) { | ||
|  | 		event->impl.set = false; | ||
|  | 	} | ||
|  | 	pthread_mutex_unlock(&event->impl.mutex); | ||
|  | } | ||
|  | 
 | ||
|  | bool kinc_event_try_to_wait(kinc_event_t *event, double seconds) { | ||
|  | 	pthread_mutex_lock(&event->impl.mutex); | ||
|  | 
 | ||
|  | 	struct timeval tv; | ||
|  | 	gettimeofday(&tv, 0); | ||
|  | 
 | ||
|  | 	int isec = (int)seconds; | ||
|  | 	int usec = (int)((seconds - isec) * 1000000.0); | ||
|  | 	struct timespec spec; | ||
|  | 	spec.tv_nsec = (tv.tv_usec + usec) * 1000; | ||
|  | 	if (spec.tv_nsec > 1000000000) { | ||
|  | 		spec.tv_nsec -= 1000000000; | ||
|  | 		isec += 1; | ||
|  | 	} | ||
|  | 	spec.tv_sec = tv.tv_sec + isec; | ||
|  | 
 | ||
|  | 	while (!event->impl.set) { | ||
|  | 		int result = pthread_cond_timedwait(&event->impl.event, &event->impl.mutex, &spec); | ||
|  | 		if (result == 0 || result == ETIMEDOUT) { | ||
|  | 			break; | ||
|  | 		} | ||
|  | 	} | ||
|  | 	bool result = event->impl.set; | ||
|  | 	if (event->impl.auto_reset) { | ||
|  | 		event->impl.set = false; | ||
|  | 	} | ||
|  | 	pthread_mutex_unlock(&event->impl.mutex); | ||
|  | 	return result; | ||
|  | } | ||
|  | 
 | ||
|  | void kinc_event_reset(kinc_event_t *event) { | ||
|  | 	pthread_mutex_lock(&event->impl.mutex); | ||
|  | 	event->impl.set = false; | ||
|  | 	pthread_mutex_unlock(&event->impl.mutex); | ||
|  | } |