changed stio_gettime() to use clock_gettime() if available.
enhanced connect timeout handling
This commit is contained in:
		
							
								
								
									
										2
									
								
								stio/configure
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								stio/configure
									
									
									
									
										vendored
									
									
								
							| @ -17509,7 +17509,7 @@ _ACEOF | |||||||
| fi | fi | ||||||
| done | done | ||||||
|  |  | ||||||
| for ac_func in timegm timelocal localtime_r gettimeofday settimeofday | for ac_func in timegm timelocal localtime_r gettimeofday settimeofday clock_gettime clock_settime | ||||||
| do : | do : | ||||||
|   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` |   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` | ||||||
| ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" | ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" | ||||||
|  | |||||||
| @ -154,7 +154,7 @@ AC_CHECK_FUNCS([wctype iswctype wctrans towctrans]) | |||||||
| AC_CHECK_FUNCS([isblank iswblank]) | AC_CHECK_FUNCS([isblank iswblank]) | ||||||
| AC_CHECK_FUNCS([lseek64 stat64 fstat64 lstat64 ftruncate64 readdir64 dirfd]) | AC_CHECK_FUNCS([lseek64 stat64 fstat64 lstat64 ftruncate64 readdir64 dirfd]) | ||||||
| AC_CHECK_FUNCS([lstat fchmod fsync ftruncate]) | AC_CHECK_FUNCS([lstat fchmod fsync ftruncate]) | ||||||
| AC_CHECK_FUNCS([timegm timelocal localtime_r gettimeofday settimeofday]) | AC_CHECK_FUNCS([timegm timelocal localtime_r gettimeofday settimeofday clock_gettime clock_settime]) | ||||||
| AC_CHECK_FUNCS([utime utimes futimes lutimes futimens]) | AC_CHECK_FUNCS([utime utimes futimes lutimes futimens]) | ||||||
| AC_CHECK_FUNCS([sysconf prctl fdopendir setrlimit getrlimit getpgid getpgrp]) | AC_CHECK_FUNCS([sysconf prctl fdopendir setrlimit getrlimit getpgid getpgrp]) | ||||||
| AC_CHECK_FUNCS([backtrace backtrace_symbols]) | AC_CHECK_FUNCS([backtrace backtrace_symbols]) | ||||||
|  | |||||||
| @ -161,7 +161,7 @@ int main () | |||||||
|  |  | ||||||
| 	memset (&sin, 0, STIO_SIZEOF(sin)); | 	memset (&sin, 0, STIO_SIZEOF(sin)); | ||||||
| 	sin.sin_family = AF_INET; | 	sin.sin_family = AF_INET; | ||||||
|  | 	memset (&tcp_make, 0, STIO_SIZEOF(&tcp_make)); | ||||||
| 	memcpy (&tcp_make.addr, &sin, STIO_SIZEOF(sin)); | 	memcpy (&tcp_make.addr, &sin, STIO_SIZEOF(sin)); | ||||||
| 	tcp_make.on_sent = tcp_on_sent; | 	tcp_make.on_sent = tcp_on_sent; | ||||||
| 	tcp_make.on_recv = tcp_on_recv; | 	tcp_make.on_recv = tcp_on_recv; | ||||||
| @ -172,23 +172,28 @@ int main () | |||||||
| 		goto oops; | 		goto oops; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	{ |  | ||||||
| 		struct sockaddr_in* p; | 	memset (&sin, 0, STIO_SIZEOF(sin)); | ||||||
| 		p = (struct sockaddr_in*)&tcp_conn.addr; | 	sin.sin_family = AF_INET; | ||||||
| 		p->sin_family = AF_INET; | 	sin.sin_port = htons(9999); | ||||||
| 		p->sin_port = htons(9999); | 	//inet_pton (sin.sin_family, "192.168.1.1", &sin.sin_addr); | ||||||
| 		inet_pton (p->sin_family, "127.0.0.1", &p->sin_addr); | 	inet_pton (sin.sin_family, "127.0.0.1", &sin.sin_addr); | ||||||
| 		tcp_conn.on_connected = tcp_on_connected; |  | ||||||
| 		tcp_conn.on_disconnected = tcp_on_disconnected; | 	memset (&tcp_conn, 0, STIO_SIZEOF(tcp_conn)); | ||||||
| 		//tcp_conn.on_failure = .... (error code? etc???) or on_connect to access success or failure??? what is better?? | 	memcpy (&tcp_conn.addr, &sin, STIO_SIZEOF(sin)); | ||||||
| 	} | 	tcp_conn.timeout.sec = 5; | ||||||
|  | 	tcp_conn.on_connected = tcp_on_connected; | ||||||
|  | 	tcp_conn.on_disconnected = tcp_on_disconnected; | ||||||
| 	if (stio_dev_tcp_connect (tcp[0], &tcp_conn) <= -1) | 	if (stio_dev_tcp_connect (tcp[0], &tcp_conn) <= -1) | ||||||
| 	{ | 	{ | ||||||
| 		printf ("stio_dev_tcp_connect() failed....\n"); | 		printf ("stio_dev_tcp_connect() failed....\n"); | ||||||
| 		goto oops; | 		goto oops; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	memset (&sin, 0, STIO_SIZEOF(sin)); | ||||||
|  | 	sin.sin_family = AF_INET; | ||||||
| 	sin.sin_port = htons(1234); | 	sin.sin_port = htons(1234); | ||||||
|  | 	memset (&tcp_make, 0, STIO_SIZEOF(&tcp_make)); | ||||||
| 	memcpy (&tcp_make.addr, &sin, STIO_SIZEOF(sin)); | 	memcpy (&tcp_make.addr, &sin, STIO_SIZEOF(sin)); | ||||||
| 	tcp_make.on_sent = tcp_on_sent; | 	tcp_make.on_sent = tcp_on_sent; | ||||||
| 	tcp_make.on_recv = tcp_on_recv; | 	tcp_make.on_recv = tcp_on_recv; | ||||||
|  | |||||||
| @ -69,6 +69,12 @@ | |||||||
| /* Define to 1 if you have the `ceilq' function. */ | /* Define to 1 if you have the `ceilq' function. */ | ||||||
| #undef HAVE_CEILQ | #undef HAVE_CEILQ | ||||||
|  |  | ||||||
|  | /* Define to 1 if you have the `clock_gettime' function. */ | ||||||
|  | #undef HAVE_CLOCK_GETTIME | ||||||
|  |  | ||||||
|  | /* Define to 1 if you have the `clock_settime' function. */ | ||||||
|  | #undef HAVE_CLOCK_SETTIME | ||||||
|  |  | ||||||
| /* Define to 1 if you have the `connect' function. */ | /* Define to 1 if you have the `connect' function. */ | ||||||
| #undef HAVE_CONNECT | #undef HAVE_CONNECT | ||||||
|  |  | ||||||
|  | |||||||
| @ -42,8 +42,7 @@ | |||||||
| #define STIO_MEMMOVE(dst,src,count) memmove(dst,src,count) | #define STIO_MEMMOVE(dst,src,count) memmove(dst,src,count) | ||||||
| #define STIO_ASSERT assert | #define STIO_ASSERT assert | ||||||
|  |  | ||||||
| typedef struct stio_tmrjob_t stio_tmrjob_t; |  | ||||||
| typedef stio_size_t stio_tmridx_t; |  | ||||||
|  |  | ||||||
| typedef void (*stio_tmr_handler_t) ( | typedef void (*stio_tmr_handler_t) ( | ||||||
| 	stio_t*             stio, | 	stio_t*             stio, | ||||||
| @ -137,9 +136,10 @@ void stio_cleartmrjobs ( | |||||||
| 	stio_t* stio | 	stio_t* stio | ||||||
| ); | ); | ||||||
|  |  | ||||||
| stio_size_t stio_firetmrjobs ( | void stio_firetmrjobs ( | ||||||
| 	stio_t*             stio, | 	stio_t*             stio, | ||||||
| 	const stio_ntime_t* tm | 	const stio_ntime_t* tm, | ||||||
|  | 	stio_size_t*        firecnt | ||||||
| ); | ); | ||||||
|  |  | ||||||
| int stio_gettmrtmout ( | int stio_gettmrtmout ( | ||||||
|  | |||||||
| @ -62,6 +62,7 @@ static int tcp_make (stio_dev_t* dev, void* ctx) | |||||||
|  |  | ||||||
| 	tcp->on_sent = arg->on_sent; | 	tcp->on_sent = arg->on_sent; | ||||||
| 	tcp->on_recv = arg->on_recv;  | 	tcp->on_recv = arg->on_recv;  | ||||||
|  | 	tcp->tmridx_connect = STIO_TMRIDX_INVALID; | ||||||
| 	return 0; | 	return 0; | ||||||
|  |  | ||||||
| oops: | oops: | ||||||
| @ -88,11 +89,17 @@ static void tcp_kill (stio_dev_t* dev) | |||||||
| { | { | ||||||
| 	stio_dev_tcp_t* tcp = (stio_dev_tcp_t*)dev; | 	stio_dev_tcp_t* tcp = (stio_dev_tcp_t*)dev; | ||||||
|  |  | ||||||
| 	if (tcp->state | (STIO_DEV_TCP_ACCEPTED | STIO_DEV_TCP_CONNECTED)) | 	if (tcp->state & (STIO_DEV_TCP_ACCEPTED | STIO_DEV_TCP_CONNECTED)) | ||||||
| 	{ | 	{ | ||||||
| 		if (tcp->on_disconnected) tcp->on_disconnected (tcp); | 		if (tcp->on_disconnected) tcp->on_disconnected (tcp); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if (tcp->tmridx_connect != STIO_TMRIDX_INVALID) | ||||||
|  | 	{ | ||||||
|  | 		stio_deltmrjob (dev->stio, tcp->tmridx_connect); | ||||||
|  | 		STIO_ASSERT (tcp->tmridx_connect == STIO_TMRIDX_INVALID); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if (tcp->sck != STIO_SCKHND_INVALID)  | 	if (tcp->sck != STIO_SCKHND_INVALID)  | ||||||
| 	{ | 	{ | ||||||
| 		stio_closeasyncsck (tcp->sck); | 		stio_closeasyncsck (tcp->sck); | ||||||
| @ -156,12 +163,16 @@ static void tmr_connect_handle (stio_t* stio, const stio_ntime_t* now, stio_tmrj | |||||||
| 		 * after it gets connected. the timer job doesn't need to be deleted | 		 * after it gets connected. the timer job doesn't need to be deleted | ||||||
| 		 * when it gets connected for this check here */ | 		 * when it gets connected for this check here */ | ||||||
| 		if (tcp->on_disconnected) tcp->on_disconnected (tcp); | 		if (tcp->on_disconnected) tcp->on_disconnected (tcp); | ||||||
|  |  | ||||||
|  | 		tcp->state &= ~STIO_DEV_TCP_CONNECTING; | ||||||
|  | 		stio_dev_tcp_kill (tcp); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| static void tmr_connect_update (stio_t* stio, stio_tmridx_t old_index, stio_tmridx_t new_index, stio_tmrjob_t* job) | static void tmr_connect_update (stio_t* stio, stio_tmridx_t old_index, stio_tmridx_t new_index, stio_tmrjob_t* job) | ||||||
| { | { | ||||||
| 	stio_dev_tcp_t* tcp = (stio_dev_tcp_t*)job->ctx; | 	stio_dev_tcp_t* tcp = (stio_dev_tcp_t*)job->ctx; | ||||||
|  | 	tcp->tmridx_connect = new_index; | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @ -217,7 +228,6 @@ static int tcp_ioctl (stio_dev_t* dev, int cmd, void* arg) | |||||||
| 		#else | 		#else | ||||||
| 			/* the socket is already non-blocking */ | 			/* the socket is already non-blocking */ | ||||||
|  |  | ||||||
|  |  | ||||||
| 			x = connect (tcp->sck, sa, sl); | 			x = connect (tcp->sck, sa, sl); | ||||||
| 			if (x == -1) | 			if (x == -1) | ||||||
| 			{ | 			{ | ||||||
| @ -231,11 +241,17 @@ static int tcp_ioctl (stio_dev_t* dev, int cmd, void* arg) | |||||||
| 						{ | 						{ | ||||||
| 							STIO_MEMSET (&tmrjob, 0, STIO_SIZEOF(tmrjob)); | 							STIO_MEMSET (&tmrjob, 0, STIO_SIZEOF(tmrjob)); | ||||||
| 							tmrjob.ctx = tcp; | 							tmrjob.ctx = tcp; | ||||||
| 							tmrjob.when = conn->timeout; | 							stio_gettime (&tmrjob.when); | ||||||
|  | 							stio_addtime (&tmrjob.when, &conn->timeout, &tmrjob.when); | ||||||
| 							tmrjob.handler = tmr_connect_handle; | 							tmrjob.handler = tmr_connect_handle; | ||||||
| 							tmrjob.updater = tmr_connect_update; | 							tmrjob.updater = tmr_connect_update; | ||||||
| 							if (stio_instmrjob (tcp->stio, &tmrjob) == STIO_TMRIDX_INVALID)  |  | ||||||
|  | 							STIO_ASSERT (tcp->tmridx_connect == STIO_TMRIDX_INVALID); | ||||||
|  | 							tcp->tmridx_connect = stio_instmrjob (tcp->stio, &tmrjob); | ||||||
|  | 							if (tcp->tmridx_connect == STIO_TMRIDX_INVALID) | ||||||
| 							{ | 							{ | ||||||
|  | 								stio_dev_event ((stio_dev_t*)tcp, STIO_DEV_EVENT_UPD, STIO_DEV_EVENT_IN); | ||||||
|  | 								/* event manipulation failure can't be handled properly. so ignore it */ | ||||||
| 								return -1; | 								return -1; | ||||||
| 							} | 							} | ||||||
| 						} | 						} | ||||||
| @ -350,13 +366,18 @@ printf ("TCP READY...%p\n", dev); | |||||||
| 				tcp->state &= ~STIO_DEV_TCP_CONNECTING; | 				tcp->state &= ~STIO_DEV_TCP_CONNECTING; | ||||||
| 				tcp->state |= STIO_DEV_TCP_CONNECTED; | 				tcp->state |= STIO_DEV_TCP_CONNECTED; | ||||||
|  |  | ||||||
| 				if (stio_dev_event ((stio_dev_t*)tcp, STIO_DEV_EVENT_UPD, STIO_DEV_EVENT_IN) <= -1) |  | ||||||
| 				if (stio_dev_event ((stio_dev_t*)tcp, STIO_DEV_EVENT_UPD, STIO_DEV_EVENT_IN) <= -1) | 				if (stio_dev_event ((stio_dev_t*)tcp, STIO_DEV_EVENT_UPD, STIO_DEV_EVENT_IN) <= -1) | ||||||
| 				{ | 				{ | ||||||
| 					printf ("CAANOT MANIPULTE EVENT ...\n"); | 					printf ("CAANOT MANIPULTE EVENT ...\n"); | ||||||
| 					return -1; | 					return -1; | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
|  | 				if (tcp->tmridx_connect != STIO_TMRIDX_INVALID) | ||||||
|  | 				{ | ||||||
|  | 					stio_deltmrjob (tcp->stio, tcp->tmridx_connect); | ||||||
|  | 					STIO_ASSERT (tcp->tmridx_connect == STIO_TMRIDX_INVALID); | ||||||
|  | 				} | ||||||
|  |  | ||||||
| 				if (tcp->on_connected (tcp) <= -1)  | 				if (tcp->on_connected (tcp) <= -1)  | ||||||
| 				{ | 				{ | ||||||
| 					printf ("ON_CONNECTE HANDLER RETURNEF FAILURE...\n"); | 					printf ("ON_CONNECTE HANDLER RETURNEF FAILURE...\n"); | ||||||
| @ -410,6 +431,8 @@ printf ("TCP READY...%p\n", dev); | |||||||
| 		clitcp->peer = peer; | 		clitcp->peer = peer; | ||||||
| 		clitcp->parent = tcp; | 		clitcp->parent = tcp; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 		/* inherit some event handlers from the parent. | 		/* inherit some event handlers from the parent. | ||||||
| 		 * you can still change them inside the on_connected handler */ | 		 * you can still change them inside the on_connected handler */ | ||||||
| 		clitcp->on_connected = tcp->on_connected; | 		clitcp->on_connected = tcp->on_connected; | ||||||
| @ -417,6 +440,7 @@ printf ("TCP READY...%p\n", dev); | |||||||
| 		clitcp->on_sent = tcp->on_sent; | 		clitcp->on_sent = tcp->on_sent; | ||||||
| 		clitcp->on_recv = tcp->on_recv; | 		clitcp->on_recv = tcp->on_recv; | ||||||
|  |  | ||||||
|  | 		clitcp->tmridx_connect = STIO_TMRIDX_INVALID; | ||||||
| 		if (clitcp->on_connected (clitcp) <= -1) stio_dev_tcp_kill (clitcp); | 		if (clitcp->on_connected (clitcp) <= -1) stio_dev_tcp_kill (clitcp); | ||||||
| 		return 0; /* success but don't invoke on_recv() */  | 		return 0; /* success but don't invoke on_recv() */  | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -62,7 +62,8 @@ struct stio_dev_tcp_t | |||||||
|  |  | ||||||
| 	stio_sckhnd_t sck; | 	stio_sckhnd_t sck; | ||||||
|  |  | ||||||
| 	unsigned int state; | 	/* bitwised-ORed of #stio_dev_tcp_state_t enumerators */ | ||||||
|  | 	int state; | ||||||
|  |  | ||||||
| 	/* peer address - valid if one of the followings is set: | 	/* peer address - valid if one of the followings is set: | ||||||
| 	 *  STIO_DEV_TCP_ACCEPTED | 	 *  STIO_DEV_TCP_ACCEPTED | ||||||
| @ -81,6 +82,8 @@ struct stio_dev_tcp_t | |||||||
| 	stio_dev_tcp_on_disconnected_t on_disconnected; | 	stio_dev_tcp_on_disconnected_t on_disconnected; | ||||||
| 	stio_dev_tcp_on_recv_t on_recv; | 	stio_dev_tcp_on_recv_t on_recv; | ||||||
| 	stio_dev_tcp_on_sent_t on_sent; | 	stio_dev_tcp_on_sent_t on_sent; | ||||||
|  |  | ||||||
|  | 	stio_tmridx_t tmridx_connect; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| typedef struct stio_dev_tcp_make_t stio_dev_tcp_make_t; | typedef struct stio_dev_tcp_make_t stio_dev_tcp_make_t; | ||||||
|  | |||||||
| @ -54,7 +54,7 @@ | |||||||
| 	#define EPOCH_DIFF_SECS  ((stio_intptr_t)EPOCH_DIFF_DAYS*24*60*60) | 	#define EPOCH_DIFF_SECS  ((stio_intptr_t)EPOCH_DIFF_DAYS*24*60*60) | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| int stio_gettime (stio_ntime_t* t) | void stio_gettime (stio_ntime_t* t) | ||||||
| { | { | ||||||
| #if defined(_WIN32) | #if defined(_WIN32) | ||||||
| 	SYSTEMTIME st; | 	SYSTEMTIME st; | ||||||
| @ -67,7 +67,7 @@ int stio_gettime (stio_ntime_t* t) | |||||||
| 	 */ | 	 */ | ||||||
|  |  | ||||||
| 	GetSystemTime (&st); | 	GetSystemTime (&st); | ||||||
| 	if (SystemTimeToFileTime (&st, &ft) == FALSE) return -1; | 	SystemTimeToFileTime (&st, &ft); /* this must not fail */ | ||||||
|  |  | ||||||
| 	li.LowPart = ft.dwLowDateTime; | 	li.LowPart = ft.dwLowDateTime; | ||||||
| 	li.HighPart = ft.dwHighDateTime; | 	li.HighPart = ft.dwHighDateTime; | ||||||
| @ -76,11 +76,8 @@ int stio_gettime (stio_ntime_t* t) | |||||||
| 	t->sec = (li.QuadPart / (STIO_NSECS_PER_SEC / 100)) - EPOCH_DIFF_SECS; | 	t->sec = (li.QuadPart / (STIO_NSECS_PER_SEC / 100)) - EPOCH_DIFF_SECS; | ||||||
| 	t->nsec = (li.QuadPart % (STIO_NSECS_PER_SEC / 100)) * 100; | 	t->nsec = (li.QuadPart % (STIO_NSECS_PER_SEC / 100)) * 100; | ||||||
|  |  | ||||||
| 	return 0; |  | ||||||
|  |  | ||||||
| #elif defined(__OS2__) | #elif defined(__OS2__) | ||||||
|  |  | ||||||
| 	APIRET rc; |  | ||||||
| 	DATETIME dt; | 	DATETIME dt; | ||||||
| 	stio_btime_t bt; | 	stio_btime_t bt; | ||||||
|  |  | ||||||
| @ -89,8 +86,8 @@ int stio_gettime (stio_ntime_t* t) | |||||||
| 	 * Maybe, resolution too low as it returns values  | 	 * Maybe, resolution too low as it returns values  | ||||||
| 	 * in seconds. */ | 	 * in seconds. */ | ||||||
|  |  | ||||||
| 	rc = DosGetDateTime (&dt); | 	DosGetDateTime (&dt); | ||||||
| 	if (rc != NO_ERROR) return -1; | 	/* DosGetDateTime() never fails. it always returns NO_ERROR */ | ||||||
|  |  | ||||||
| 	bt.year = dt.year - STIO_BTIME_YEAR_BASE; | 	bt.year = dt.year - STIO_BTIME_YEAR_BASE; | ||||||
| 	bt.mon = dt.month - 1; | 	bt.mon = dt.month - 1; | ||||||
| @ -101,8 +98,15 @@ int stio_gettime (stio_ntime_t* t) | |||||||
| 	/*bt.msec = dt.hundredths * 10;*/ | 	/*bt.msec = dt.hundredths * 10;*/ | ||||||
| 	bt.isdst = -1; /* determine dst for me */ | 	bt.isdst = -1; /* determine dst for me */ | ||||||
|  |  | ||||||
| 	if (stio_timelocal (&bt, t) <= -1) return -1; | 	if (stio_timelocal (&bt, t) <= -1)  | ||||||
| 	t->nsec = STIO_MSEC_TO_NSEC(dt.hundredths * 10); | 	{ | ||||||
|  | 		t->sec = time (STIO_NULL); | ||||||
|  | 		t->nsec = 0; | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		t->nsec = STIO_MSEC_TO_NSEC(dt.hundredths * 10); | ||||||
|  | 	} | ||||||
| 	return 0; | 	return 0; | ||||||
|  |  | ||||||
| #elif defined(__DOS__) | #elif defined(__DOS__) | ||||||
| @ -123,41 +127,51 @@ int stio_gettime (stio_ntime_t* t) | |||||||
| 	/*bt.msec = dt.hsecond * 10; */ | 	/*bt.msec = dt.hsecond * 10; */ | ||||||
| 	bt.isdst = -1; /* determine dst for me */ | 	bt.isdst = -1; /* determine dst for me */ | ||||||
|  |  | ||||||
| 	if (stio_timelocal (&bt, t) <= -1) return -1; | 	if (stio_timelocal (&bt, t) <= -1)  | ||||||
| 	t->nsec = STIO_MSEC_TO_NSEC(dt.hsecond * 10); | 	{ | ||||||
| 	return 0; | 		t->sec = time (STIO_NULL); | ||||||
|  | 		t->nsec = 0; | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		t->nsec = STIO_MSEC_TO_NSEC(dt.hsecond * 10); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| #elif defined(macintosh) | #elif defined(macintosh) | ||||||
| 	unsigned long tv; | 	unsigned long tv; | ||||||
|  |  | ||||||
| 	GetDateTime (&tv); | 	GetDateTime (&tv); | ||||||
|  |  | ||||||
| 	t->sec = tv; | 	t->sec = tv; | ||||||
| 	tv->nsec = 0; | 	tv->nsec = 0; | ||||||
| 	 |  | ||||||
| 	return 0; | #elif defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_REALTIME) | ||||||
|  | 	struct timespec ts; | ||||||
|  |  | ||||||
|  | 	if (clock_gettime (CLOCK_REALTIME, &ts) == -1 && errno == EINVAL) | ||||||
|  | 	{ | ||||||
|  | 	#if defined(HAVE_GETTIMEOFDAY) | ||||||
|  | 		struct timeval tv; | ||||||
|  | 		gettimeofday (&tv, STIO_NULL); | ||||||
|  | 		t->sec = tv.tv_sec; | ||||||
|  | 		t->nsec = STIO_USEC_TO_NSEC(tv.tv_usec); | ||||||
|  | 	#else | ||||||
|  | 		t->sec = time (STIO_NULL); | ||||||
|  | 		t->nsec = 0; | ||||||
|  | 	#endif | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	t->sec = ts.tv_sec; | ||||||
|  | 	t->nsec = ts.tv_nsec; | ||||||
|  |  | ||||||
| #elif defined(HAVE_GETTIMEOFDAY) | #elif defined(HAVE_GETTIMEOFDAY) | ||||||
| 	struct timeval tv; | 	struct timeval tv; | ||||||
| 	int n; | 	gettimeofday (&tv, STIO_NULL); | ||||||
|  |  | ||||||
| 	/* TODO: consider using clock_gettime() if it's avaialble.. -lrt may be needed */ |  | ||||||
| 	n = gettimeofday (&tv, STIO_NULL); |  | ||||||
| 	if (n == -1)  |  | ||||||
| 	{ |  | ||||||
| /* TODO: set stio->errnum using errno... */ |  | ||||||
| 		return -1; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	t->sec = tv.tv_sec; | 	t->sec = tv.tv_sec; | ||||||
| 	t->nsec = STIO_USEC_TO_NSEC(tv.tv_usec); | 	t->nsec = STIO_USEC_TO_NSEC(tv.tv_usec); | ||||||
| 	return 0; |  | ||||||
|  |  | ||||||
| #else | #else | ||||||
| 	t->sec = STIO_TIME (STIO_NULL); | 	t->sec = time (STIO_NULL); | ||||||
| 	t->nsec = 0; | 	t->nsec = 0; | ||||||
|  |  | ||||||
| 	return 0; |  | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
|  |  | ||||||
|  | |||||||
| @ -106,7 +106,7 @@ extern "C" { | |||||||
| /** | /** | ||||||
|  * The stio_gettime() function gets the current time. |  * The stio_gettime() function gets the current time. | ||||||
|  */ |  */ | ||||||
| STIO_EXPORT int stio_gettime ( | STIO_EXPORT void stio_gettime ( | ||||||
| 	stio_ntime_t* nt | 	stio_ntime_t* nt | ||||||
| ); | ); | ||||||
|  |  | ||||||
|  | |||||||
| @ -172,35 +172,35 @@ stio_tmridx_t stio_updtmrjob (stio_t* stio, stio_size_t index, const stio_tmrjob | |||||||
| 	return YOUNGER_THAN(job, &item)? sift_up (stio, index, 0): sift_down (stio, index, 0); | 	return YOUNGER_THAN(job, &item)? sift_up (stio, index, 0): sift_down (stio, index, 0); | ||||||
| } | } | ||||||
|  |  | ||||||
| stio_size_t stio_firetmrjobs (stio_t* stio, const stio_ntime_t* tm) | void stio_firetmrjobs (stio_t* stio, const stio_ntime_t* tm, stio_size_t* firecnt) | ||||||
| { | { | ||||||
| 	stio_ntime_t now; | 	stio_ntime_t now; | ||||||
| 	stio_tmrjob_t event; | 	stio_tmrjob_t event; | ||||||
| 	stio_size_t fire_count = 0; | 	stio_size_t count = 0; | ||||||
|  |  | ||||||
| 	/* if the current time is not specified, get it from the system */ | 	/* if the current time is not specified, get it from the system */ | ||||||
| 	if (tm) now = *tm; | 	if (tm) now = *tm; | ||||||
| 	else if (stio_gettime (&now) <= -1) return -1; | 	else stio_gettime (&now); | ||||||
|  |  | ||||||
| 	while (stio->tmr.size > 0) | 	while (stio->tmr.size > 0) | ||||||
| 	{ | 	{ | ||||||
| 		if (stio_cmptime(&stio->tmr.jobs[0].when, &now) > 0) break; | 		if (stio_cmptime(&stio->tmr.jobs[0].when, &now) > 0) break; | ||||||
|  |  | ||||||
| 		event = stio->tmr.jobs[0]; | 		event = stio->tmr.jobs[0]; | ||||||
| 		stio_deltmrjob (stio, 0); /* remove the registered event structure */ | 		stio_deltmrjob (stio, 0); /* remove the registered job */ | ||||||
|  |  | ||||||
| 		fire_count++; | 		count++; | ||||||
| 		event.handler (stio, &now, &event); /* then fire the event */ | 		event.handler (stio, &now, &event); /* then fire the job */ | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return fire_count; | 	if (firecnt) *firecnt = count; | ||||||
| } | } | ||||||
|  |  | ||||||
| int stio_gettmrtmout (stio_t* stio, const stio_ntime_t* tm, stio_ntime_t* tmout) | int stio_gettmrtmout (stio_t* stio, const stio_ntime_t* tm, stio_ntime_t* tmout) | ||||||
| { | { | ||||||
| 	stio_ntime_t now; | 	stio_ntime_t now; | ||||||
|  |  | ||||||
| 	/* time-out can't be calculated when there's no event scheduled */ | 	/* time-out can't be calculated when there's no job scheduled */ | ||||||
| 	if (stio->tmr.size <= 0)  | 	if (stio->tmr.size <= 0)  | ||||||
| 	{ | 	{ | ||||||
| 		stio->errnum = STIO_ENOENT; | 		stio->errnum = STIO_ENOENT; | ||||||
| @ -209,7 +209,7 @@ int stio_gettmrtmout (stio_t* stio, const stio_ntime_t* tm, stio_ntime_t* tmout) | |||||||
|  |  | ||||||
| 	/* if the current time is not specified, get it from the system */ | 	/* if the current time is not specified, get it from the system */ | ||||||
| 	if (tm) now = *tm; | 	if (tm) now = *tm; | ||||||
| 	else if (stio_gettime (&now) <= -1) return -1; | 	else stio_gettime (&now); | ||||||
|  |  | ||||||
| 	stio_subtime (&stio->tmr.jobs[0].when, &now, tmout); | 	stio_subtime (&stio->tmr.jobs[0].when, &now, tmout); | ||||||
| 	if (tmout->sec < 0) stio_cleartime (tmout); | 	if (tmout->sec < 0) stio_cleartime (tmout); | ||||||
|  | |||||||
| @ -227,15 +227,17 @@ int stio_exec (stio_t* stio) | |||||||
|  |  | ||||||
| 	/*if (!stio->dev.head) return 0;*/ | 	/*if (!stio->dev.head) return 0;*/ | ||||||
|  |  | ||||||
| 	 | 	/* execute the scheduled jobs before checking devices with the  | ||||||
|  | 	 * multiplexer. the scheduled jobs can safely destroy the devices */ | ||||||
|  | 	stio_firetmrjobs (stio, STIO_NULL, STIO_NULL); | ||||||
|  |  | ||||||
| 	if (stio_gettmrtmout (stio, STIO_NULL, &tmout) <= -1) | 	if (stio_gettmrtmout (stio, STIO_NULL, &tmout) <= -1) | ||||||
| 	{ | 	{ | ||||||
| 		/* defaults to 1 second if timeout can't be acquired */ | 		/* defaults to 1 second if timeout can't be acquired */ | ||||||
| 		tmout.sec = 1; | 		tmout.sec = 1; /* TODO: make the default timeout configurable */ | ||||||
| 		tmout.nsec = 0; | 		tmout.nsec = 0; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  |  | ||||||
| #if defined(_WIN32) | #if defined(_WIN32) | ||||||
| /* | /* | ||||||
| 	if (GetQueuedCompletionStatusEx (stio->iocp, stio->ovls, STIO_COUNTOF(stio->ovls), &nentries, timeout, FALSE) == FALSE) | 	if (GetQueuedCompletionStatusEx (stio->iocp, stio->ovls, STIO_COUNTOF(stio->ovls), &nentries, timeout, FALSE) == FALSE) | ||||||
|  | |||||||
| @ -29,6 +29,9 @@ | |||||||
|  |  | ||||||
| #include <stio-cmn.h> | #include <stio-cmn.h> | ||||||
|  |  | ||||||
|  | typedef struct stio_tmrjob_t stio_tmrjob_t; | ||||||
|  | typedef stio_size_t stio_tmridx_t; | ||||||
|  |  | ||||||
| struct stio_sckadr_t | struct stio_sckadr_t | ||||||
| { | { | ||||||
| 	int family; | 	int family; | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user