changed stio_gettime() to use clock_gettime() if available.
enhanced connect timeout handling
This commit is contained in:
parent
9b901e924c
commit
15652f70e4
2
stio/configure
vendored
2
stio/configure
vendored
@ -17509,7 +17509,7 @@ _ACEOF
|
||||
fi
|
||||
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 :
|
||||
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
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([lseek64 stat64 fstat64 lstat64 ftruncate64 readdir64 dirfd])
|
||||
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([sysconf prctl fdopendir setrlimit getrlimit getpgid getpgrp])
|
||||
AC_CHECK_FUNCS([backtrace backtrace_symbols])
|
||||
|
@ -161,7 +161,7 @@ int main ()
|
||||
|
||||
memset (&sin, 0, STIO_SIZEOF(sin));
|
||||
sin.sin_family = AF_INET;
|
||||
|
||||
memset (&tcp_make, 0, STIO_SIZEOF(&tcp_make));
|
||||
memcpy (&tcp_make.addr, &sin, STIO_SIZEOF(sin));
|
||||
tcp_make.on_sent = tcp_on_sent;
|
||||
tcp_make.on_recv = tcp_on_recv;
|
||||
@ -172,23 +172,28 @@ int main ()
|
||||
goto oops;
|
||||
}
|
||||
|
||||
{
|
||||
struct sockaddr_in* p;
|
||||
p = (struct sockaddr_in*)&tcp_conn.addr;
|
||||
p->sin_family = AF_INET;
|
||||
p->sin_port = htons(9999);
|
||||
inet_pton (p->sin_family, "127.0.0.1", &p->sin_addr);
|
||||
|
||||
memset (&sin, 0, STIO_SIZEOF(sin));
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = htons(9999);
|
||||
//inet_pton (sin.sin_family, "192.168.1.1", &sin.sin_addr);
|
||||
inet_pton (sin.sin_family, "127.0.0.1", &sin.sin_addr);
|
||||
|
||||
memset (&tcp_conn, 0, STIO_SIZEOF(tcp_conn));
|
||||
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;
|
||||
//tcp_conn.on_failure = .... (error code? etc???) or on_connect to access success or failure??? what is better??
|
||||
}
|
||||
if (stio_dev_tcp_connect (tcp[0], &tcp_conn) <= -1)
|
||||
{
|
||||
printf ("stio_dev_tcp_connect() failed....\n");
|
||||
goto oops;
|
||||
}
|
||||
|
||||
memset (&sin, 0, STIO_SIZEOF(sin));
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = htons(1234);
|
||||
memset (&tcp_make, 0, STIO_SIZEOF(&tcp_make));
|
||||
memcpy (&tcp_make.addr, &sin, STIO_SIZEOF(sin));
|
||||
tcp_make.on_sent = tcp_on_sent;
|
||||
tcp_make.on_recv = tcp_on_recv;
|
||||
|
@ -69,6 +69,12 @@
|
||||
/* Define to 1 if you have the `ceilq' function. */
|
||||
#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. */
|
||||
#undef HAVE_CONNECT
|
||||
|
||||
|
@ -42,8 +42,7 @@
|
||||
#define STIO_MEMMOVE(dst,src,count) memmove(dst,src,count)
|
||||
#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) (
|
||||
stio_t* stio,
|
||||
@ -137,9 +136,10 @@ void stio_cleartmrjobs (
|
||||
stio_t* stio
|
||||
);
|
||||
|
||||
stio_size_t stio_firetmrjobs (
|
||||
void stio_firetmrjobs (
|
||||
stio_t* stio,
|
||||
const stio_ntime_t* tm
|
||||
const stio_ntime_t* tm,
|
||||
stio_size_t* firecnt
|
||||
);
|
||||
|
||||
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_recv = arg->on_recv;
|
||||
tcp->tmridx_connect = STIO_TMRIDX_INVALID;
|
||||
return 0;
|
||||
|
||||
oops:
|
||||
@ -88,11 +89,17 @@ static void tcp_kill (stio_dev_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->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)
|
||||
{
|
||||
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
|
||||
* when it gets connected for this check here */
|
||||
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)
|
||||
{
|
||||
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
|
||||
/* the socket is already non-blocking */
|
||||
|
||||
|
||||
x = connect (tcp->sck, sa, sl);
|
||||
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));
|
||||
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.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;
|
||||
}
|
||||
}
|
||||
@ -350,13 +366,18 @@ printf ("TCP READY...%p\n", dev);
|
||||
tcp->state &= ~STIO_DEV_TCP_CONNECTING;
|
||||
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)
|
||||
{
|
||||
printf ("CAANOT MANIPULTE EVENT ...\n");
|
||||
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)
|
||||
{
|
||||
printf ("ON_CONNECTE HANDLER RETURNEF FAILURE...\n");
|
||||
@ -410,6 +431,8 @@ printf ("TCP READY...%p\n", dev);
|
||||
clitcp->peer = peer;
|
||||
clitcp->parent = tcp;
|
||||
|
||||
|
||||
|
||||
/* inherit some event handlers from the parent.
|
||||
* you can still change them inside the on_connected handler */
|
||||
clitcp->on_connected = tcp->on_connected;
|
||||
@ -417,6 +440,7 @@ printf ("TCP READY...%p\n", dev);
|
||||
clitcp->on_sent = tcp->on_sent;
|
||||
clitcp->on_recv = tcp->on_recv;
|
||||
|
||||
clitcp->tmridx_connect = STIO_TMRIDX_INVALID;
|
||||
if (clitcp->on_connected (clitcp) <= -1) stio_dev_tcp_kill (clitcp);
|
||||
return 0; /* success but don't invoke on_recv() */
|
||||
}
|
||||
|
@ -62,7 +62,8 @@ struct stio_dev_tcp_t
|
||||
|
||||
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:
|
||||
* 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_recv_t on_recv;
|
||||
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;
|
||||
|
@ -54,7 +54,7 @@
|
||||
#define EPOCH_DIFF_SECS ((stio_intptr_t)EPOCH_DIFF_DAYS*24*60*60)
|
||||
#endif
|
||||
|
||||
int stio_gettime (stio_ntime_t* t)
|
||||
void stio_gettime (stio_ntime_t* t)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
SYSTEMTIME st;
|
||||
@ -67,7 +67,7 @@ int stio_gettime (stio_ntime_t* t)
|
||||
*/
|
||||
|
||||
GetSystemTime (&st);
|
||||
if (SystemTimeToFileTime (&st, &ft) == FALSE) return -1;
|
||||
SystemTimeToFileTime (&st, &ft); /* this must not fail */
|
||||
|
||||
li.LowPart = ft.dwLowDateTime;
|
||||
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->nsec = (li.QuadPart % (STIO_NSECS_PER_SEC / 100)) * 100;
|
||||
|
||||
return 0;
|
||||
|
||||
#elif defined(__OS2__)
|
||||
|
||||
APIRET rc;
|
||||
DATETIME dt;
|
||||
stio_btime_t bt;
|
||||
|
||||
@ -89,8 +86,8 @@ int stio_gettime (stio_ntime_t* t)
|
||||
* Maybe, resolution too low as it returns values
|
||||
* in seconds. */
|
||||
|
||||
rc = DosGetDateTime (&dt);
|
||||
if (rc != NO_ERROR) return -1;
|
||||
DosGetDateTime (&dt);
|
||||
/* DosGetDateTime() never fails. it always returns NO_ERROR */
|
||||
|
||||
bt.year = dt.year - STIO_BTIME_YEAR_BASE;
|
||||
bt.mon = dt.month - 1;
|
||||
@ -101,8 +98,15 @@ int stio_gettime (stio_ntime_t* t)
|
||||
/*bt.msec = dt.hundredths * 10;*/
|
||||
bt.isdst = -1; /* determine dst for me */
|
||||
|
||||
if (stio_timelocal (&bt, t) <= -1) return -1;
|
||||
if (stio_timelocal (&bt, t) <= -1)
|
||||
{
|
||||
t->sec = time (STIO_NULL);
|
||||
t->nsec = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
t->nsec = STIO_MSEC_TO_NSEC(dt.hundredths * 10);
|
||||
}
|
||||
return 0;
|
||||
|
||||
#elif defined(__DOS__)
|
||||
@ -123,41 +127,51 @@ int stio_gettime (stio_ntime_t* t)
|
||||
/*bt.msec = dt.hsecond * 10; */
|
||||
bt.isdst = -1; /* determine dst for me */
|
||||
|
||||
if (stio_timelocal (&bt, t) <= -1) return -1;
|
||||
if (stio_timelocal (&bt, t) <= -1)
|
||||
{
|
||||
t->sec = time (STIO_NULL);
|
||||
t->nsec = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
t->nsec = STIO_MSEC_TO_NSEC(dt.hsecond * 10);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#elif defined(macintosh)
|
||||
unsigned long tv;
|
||||
|
||||
GetDateTime (&tv);
|
||||
|
||||
t->sec = tv;
|
||||
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)
|
||||
struct timeval tv;
|
||||
int n;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
gettimeofday (&tv, STIO_NULL);
|
||||
t->sec = tv.tv_sec;
|
||||
t->nsec = STIO_USEC_TO_NSEC(tv.tv_usec);
|
||||
return 0;
|
||||
|
||||
#else
|
||||
t->sec = STIO_TIME (STIO_NULL);
|
||||
t->sec = time (STIO_NULL);
|
||||
t->nsec = 0;
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -106,7 +106,7 @@ extern "C" {
|
||||
/**
|
||||
* The stio_gettime() function gets the current time.
|
||||
*/
|
||||
STIO_EXPORT int stio_gettime (
|
||||
STIO_EXPORT void stio_gettime (
|
||||
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);
|
||||
}
|
||||
|
||||
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_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 (tm) now = *tm;
|
||||
else if (stio_gettime (&now) <= -1) return -1;
|
||||
else stio_gettime (&now);
|
||||
|
||||
while (stio->tmr.size > 0)
|
||||
{
|
||||
if (stio_cmptime(&stio->tmr.jobs[0].when, &now) > 0) break;
|
||||
|
||||
event = stio->tmr.jobs[0];
|
||||
stio_deltmrjob (stio, 0); /* remove the registered event structure */
|
||||
stio_deltmrjob (stio, 0); /* remove the registered job */
|
||||
|
||||
fire_count++;
|
||||
event.handler (stio, &now, &event); /* then fire the event */
|
||||
count++;
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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 (tm) now = *tm;
|
||||
else if (stio_gettime (&now) <= -1) return -1;
|
||||
else stio_gettime (&now);
|
||||
|
||||
stio_subtime (&stio->tmr.jobs[0].when, &now, tmout);
|
||||
if (tmout->sec < 0) stio_cleartime (tmout);
|
||||
|
@ -227,15 +227,17 @@ int stio_exec (stio_t* stio)
|
||||
|
||||
/*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)
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
||||
#if defined(_WIN32)
|
||||
/*
|
||||
if (GetQueuedCompletionStatusEx (stio->iocp, stio->ovls, STIO_COUNTOF(stio->ovls), &nentries, timeout, FALSE) == FALSE)
|
||||
|
@ -29,6 +29,9 @@
|
||||
|
||||
#include <stio-cmn.h>
|
||||
|
||||
typedef struct stio_tmrjob_t stio_tmrjob_t;
|
||||
typedef stio_size_t stio_tmridx_t;
|
||||
|
||||
struct stio_sckadr_t
|
||||
{
|
||||
int family;
|
||||
|
Loading…
Reference in New Issue
Block a user