mirror of
https://github.com/stefanocasazza/ULib.git
synced 2025-09-28 19:05:55 +08:00
some fix
This commit is contained in:
parent
7886a7954e
commit
7731ca80a0
|
@ -17,21 +17,21 @@
|
||||||
// Design by contract - if (expr == false) then stop
|
// Design by contract - if (expr == false) then stop
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
# define U_ASSERT(expr) { int _status_ = UTrace::suspend(); U_INTERNAL_ASSERT(expr); UTrace::resume(_status_); }
|
# define U_ASSERT(expr) { UTrace::suspend(); U_INTERNAL_ASSERT(expr); UTrace::resume(); }
|
||||||
# define U_ASSERT_MINOR(a,b) { int _status_ = UTrace::suspend(); U_INTERNAL_ASSERT_MINOR(a,b); UTrace::resume(_status_); }
|
# define U_ASSERT_MINOR(a,b) { UTrace::suspend(); U_INTERNAL_ASSERT_MINOR(a,b); UTrace::resume(); }
|
||||||
# define U_ASSERT_MAJOR(a,b) { int _status_ = UTrace::suspend(); U_INTERNAL_ASSERT_MAJOR(a,b); UTrace::resume(_status_); }
|
# define U_ASSERT_MAJOR(a,b) { UTrace::suspend(); U_INTERNAL_ASSERT_MAJOR(a,b); UTrace::resume(); }
|
||||||
# define U_ASSERT_EQUALS(a,b) { int _status_ = UTrace::suspend(); U_INTERNAL_ASSERT_EQUALS(a,b); UTrace::resume(_status_); }
|
# define U_ASSERT_EQUALS(a,b) { UTrace::suspend(); U_INTERNAL_ASSERT_EQUALS(a,b); UTrace::resume(); }
|
||||||
# define U_ASSERT_DIFFERS(a,b) { int _status_ = UTrace::suspend(); U_INTERNAL_ASSERT_DIFFERS(a,b); UTrace::resume(_status_); }
|
# define U_ASSERT_DIFFERS(a,b) { UTrace::suspend(); U_INTERNAL_ASSERT_DIFFERS(a,b); UTrace::resume(); }
|
||||||
# define U_ASSERT_POINTER(ptr) { int _status_ = UTrace::suspend(); U_INTERNAL_ASSERT_POINTER(ptr); UTrace::resume(_status_); }
|
# define U_ASSERT_POINTER(ptr) { UTrace::suspend(); U_INTERNAL_ASSERT_POINTER(ptr); UTrace::resume(); }
|
||||||
# define U_ASSERT_RANGE(a,x,b) { int _status_ = UTrace::suspend(); U_INTERNAL_ASSERT_RANGE(a,x,b); UTrace::resume(_status_); }
|
# define U_ASSERT_RANGE(a,x,b) { UTrace::suspend(); U_INTERNAL_ASSERT_RANGE(a,x,b); UTrace::resume(); }
|
||||||
|
|
||||||
# define U_ASSERT_MSG(expr,info) { int _status_ = UTrace::suspend(); U_INTERNAL_ASSERT_MSG(expr,info); UTrace::resume(_status_); }
|
# define U_ASSERT_MSG(expr,info) { UTrace::suspend(); U_INTERNAL_ASSERT_MSG(expr,info); UTrace::resume(); }
|
||||||
# define U_ASSERT_MINOR_MSG(a,b,info) { int _status_ = UTrace::suspend(); U_INTERNAL_ASSERT_MINOR_MSG(a,b,info); UTrace::resume(_status_); }
|
# define U_ASSERT_MINOR_MSG(a,b,info) { UTrace::suspend(); U_INTERNAL_ASSERT_MINOR_MSG(a,b,info); UTrace::resume(); }
|
||||||
# define U_ASSERT_MAJOR_MSG(a,b,info) { int _status_ = UTrace::suspend(); U_INTERNAL_ASSERT_MAJOR_MSG(a,b,info); UTrace::resume(_status_); }
|
# define U_ASSERT_MAJOR_MSG(a,b,info) { UTrace::suspend(); U_INTERNAL_ASSERT_MAJOR_MSG(a,b,info); UTrace::resume(); }
|
||||||
# define U_ASSERT_EQUALS_MSG(a,b,info) { int _status_ = UTrace::suspend(); U_INTERNAL_ASSERT_EQUALS_MSG(a,b,info); UTrace::resume(_status_); }
|
# define U_ASSERT_EQUALS_MSG(a,b,info) { UTrace::suspend(); U_INTERNAL_ASSERT_EQUALS_MSG(a,b,info); UTrace::resume(); }
|
||||||
# define U_ASSERT_DIFFERS_MSG(a,b,info) { int _status_ = UTrace::suspend(); U_INTERNAL_ASSERT_DIFFERS_MSG(a,b,info); UTrace::resume(_status_); }
|
# define U_ASSERT_DIFFERS_MSG(a,b,info) { UTrace::suspend(); U_INTERNAL_ASSERT_DIFFERS_MSG(a,b,info); UTrace::resume(); }
|
||||||
# define U_ASSERT_POINTER_MSG(ptr,info) { int _status_ = UTrace::suspend(); U_INTERNAL_ASSERT_POINTER_MSG(ptr,info); UTrace::resume(_status_); }
|
# define U_ASSERT_POINTER_MSG(ptr,info) { UTrace::suspend(); U_INTERNAL_ASSERT_POINTER_MSG(ptr,info); UTrace::resume(); }
|
||||||
# define U_ASSERT_RANGE_MSG(a,x,b,info) { int _status_ = UTrace::suspend(); U_INTERNAL_ASSERT_RANGE_MSG(a,x,b,info); UTrace::resume(_status_); }
|
# define U_ASSERT_RANGE_MSG(a,x,b,info) { UTrace::suspend(); U_INTERNAL_ASSERT_RANGE_MSG(a,x,b,info); UTrace::resume(); }
|
||||||
#elif defined(U_TEST)
|
#elif defined(U_TEST)
|
||||||
# define U_ASSERT(expr) U_INTERNAL_ASSERT(expr)
|
# define U_ASSERT(expr) U_INTERNAL_ASSERT(expr)
|
||||||
# define U_ASSERT_MINOR(a,b) U_INTERNAL_ASSERT_MINOR(a,b)
|
# define U_ASSERT_MINOR(a,b) U_INTERNAL_ASSERT_MINOR(a,b)
|
||||||
|
@ -85,20 +85,20 @@
|
||||||
|
|
||||||
// NB: U_DUMP, U_SYSCALL() and U_RETURN() depend on presence of U_TRACE()
|
// NB: U_DUMP, U_SYSCALL() and U_RETURN() depend on presence of U_TRACE()
|
||||||
|
|
||||||
# define U_INTERNAL_DUMP(args...) { if (utr.active[0]) u_trace_dump(args); }
|
# define U_INTERNAL_DUMP(args...) { if (utr.active[0]) u_trace_dump(args); }
|
||||||
# define U_DUMP(args...) { if (utr.active[0]) { int _status_ = UTrace::suspend(); u_trace_dump(args); UTrace::resume(_status_); } }
|
# define U_DUMP(args...) { if (utr.active[0]) { UTrace::suspend(); u_trace_dump(args); UTrace::resume(); } }
|
||||||
|
|
||||||
# define U_SYSCALL(name,format,args...) (utr.trace_syscall("::"#name"(" format ")" , ##args), \
|
|
||||||
utr.trace_sysreturn_type(::name(args)))
|
|
||||||
|
|
||||||
# define U_SYSCALL_NO_PARAM(name) (utr.trace_syscall("::"#name"()",0), \
|
# define U_SYSCALL_NO_PARAM(name) (utr.trace_syscall("::"#name"()",0), \
|
||||||
utr.trace_sysreturn_type(::name()))
|
utr.trace_sysreturn_type(::name()))
|
||||||
|
|
||||||
# define U_SYSCALL_VOID(name,format,args...) {utr.trace_syscall("::"#name"(" format ")" , ##args); \
|
# define U_SYSCALL_VOID_NO_PARAM(name) { utr.trace_syscall("::"#name"()",0); \
|
||||||
name(args); utr.trace_sysreturn(false,0);}
|
name(); utr.trace_sysreturn(false,0); }
|
||||||
|
|
||||||
# define U_SYSCALL_VOID_NO_PARAM(name) {utr.trace_syscall("::"#name"()",0); \
|
# define U_SYSCALL(name,format,args...) (UTrace::suspend(), utr.trace_syscall("::"#name"(" format ")" , ##args), \
|
||||||
name(); utr.trace_sysreturn(false,0);}
|
UTrace::resume(), utr.trace_sysreturn_type(::name(args)))
|
||||||
|
|
||||||
|
# define U_SYSCALL_VOID(name,format,args...) { UTrace::suspend(); utr.trace_syscall("::"#name"(" format ")" , ##args); \
|
||||||
|
UTrace::resume(); ::name(args); utr.trace_sysreturn(false,0); }
|
||||||
|
|
||||||
# define U_RETURN(r) return (utr.trace_return_type((r)))
|
# define U_RETURN(r) return (utr.trace_return_type((r)))
|
||||||
# define U_RETURN_STRING(str) {U_INTERNAL_ASSERT((str).invariant()); return (utr.trace_return("%V",(str).rep),(str));}
|
# define U_RETURN_STRING(str) {U_INTERNAL_ASSERT((str).invariant()); return (utr.trace_return("%V",(str).rep),(str));}
|
||||||
|
|
|
@ -51,6 +51,8 @@ typedef const unsigned char* pcuchar_t;
|
||||||
// typedef int (*x11error_t) (void*, void*);
|
// typedef int (*x11error_t) (void*, void*);
|
||||||
// typedef int (*x11IOerror_t)(void*);
|
// typedef int (*x11IOerror_t)(void*);
|
||||||
|
|
||||||
|
class UCrono;
|
||||||
|
|
||||||
class U_EXPORT UTrace {
|
class U_EXPORT UTrace {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -121,13 +123,16 @@ public:
|
||||||
U_MANAGE_SYSRETURN_VALUE(tdbdata_t, "%J", false)
|
U_MANAGE_SYSRETURN_VALUE(tdbdata_t, "%J", false)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int suspend() { int status = u_trace_suspend; u_trace_suspend = 1; return status; }
|
static void resume() { u_trace_suspend = status; }
|
||||||
static void resume(int status) { u_trace_suspend = status; }
|
static void suspend() { status = u_trace_suspend; u_trace_suspend = 1; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char buffer_trace[1019], buffer_syscall[1019];
|
char buffer_trace[1019], buffer_syscall[1019];
|
||||||
uint32_t buffer_trace_len, buffer_syscall_len;
|
uint32_t buffer_trace_len, buffer_syscall_len;
|
||||||
|
|
||||||
|
static int status;
|
||||||
|
static UCrono* time_syscall_read_or_write;
|
||||||
|
|
||||||
void set(int level) U_NO_EXPORT;
|
void set(int level) U_NO_EXPORT;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
#include <ulib/timeval.h>
|
#include <ulib/timeval.h>
|
||||||
|
|
||||||
|
class UTimer;
|
||||||
|
class UNotifier;
|
||||||
#ifdef USE_LIBEVENT
|
#ifdef USE_LIBEVENT
|
||||||
template <class T> class UTimerEv;
|
template <class T> class UTimerEv;
|
||||||
#endif
|
#endif
|
||||||
|
@ -25,48 +27,24 @@ public:
|
||||||
|
|
||||||
struct timeval ctime;
|
struct timeval ctime;
|
||||||
|
|
||||||
void reset() { ctime.tv_sec = ctime.tv_usec = 0L; }
|
UEventTime(long sec = 0L, long micro_sec = 1L);
|
||||||
|
|
||||||
UEventTime(long sec = 0L, long usec = 1L);
|
|
||||||
virtual ~UEventTime();
|
virtual ~UEventTime();
|
||||||
|
|
||||||
bool operator<(const UEventTime& t) const __pure;
|
bool operator<(const UEventTime& t) const __pure;
|
||||||
|
|
||||||
// SERVICES
|
// SERVICES
|
||||||
|
|
||||||
void setTime(long timeoutMS)
|
bool isExpired() const __pure
|
||||||
{
|
{
|
||||||
U_TRACE(0, "UEventTime::setTime(%ld)", timeoutMS)
|
U_TRACE_NO_PARAM(0, "UEventTime::isExpired()")
|
||||||
|
|
||||||
setCurrentTime();
|
|
||||||
|
|
||||||
UTimeVal::setMilliSecond(timeoutMS);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setCurrentTime()
|
|
||||||
{
|
|
||||||
U_TRACE_NO_PARAM(1, "UEventTime::setCurrentTime()")
|
|
||||||
|
|
||||||
U_CHECK_MEMORY
|
U_CHECK_MEMORY
|
||||||
|
|
||||||
(void) U_SYSCALL(gettimeofday, "%p,%p", &ctime, 0);
|
long diff1 = ctime.tv_sec + tv_sec - u_now->tv_sec,
|
||||||
|
|
||||||
U_INTERNAL_DUMP("ctime = { %ld %6ld }", ctime.tv_sec, ctime.tv_usec)
|
|
||||||
}
|
|
||||||
|
|
||||||
time_t expire() const { return (ctime.tv_sec + tv_sec); }
|
|
||||||
|
|
||||||
bool isExpired(long tolerance) const __pure
|
|
||||||
{
|
|
||||||
U_TRACE(0, "UEventTime::isExpired(%ld)", tolerance)
|
|
||||||
|
|
||||||
U_CHECK_MEMORY
|
|
||||||
|
|
||||||
long t1 = expire(),
|
|
||||||
diff1 = t1 - u_now->tv_sec,
|
|
||||||
diff2 = ctime.tv_usec + tv_usec - u_now->tv_usec;
|
diff2 = ctime.tv_usec + tv_usec - u_now->tv_usec;
|
||||||
|
|
||||||
U_INTERNAL_DUMP("this = { %ld %6ld }, diff1 = %ld diff2 = %ld", t1, ctime.tv_usec + tv_usec, diff1, diff2)
|
U_INTERNAL_DUMP("this = { %ld %6ld }, diff1 = %ld diff2 = %ld", ctime.tv_sec + tv_sec,
|
||||||
|
ctime.tv_usec + tv_usec, diff1, diff2)
|
||||||
|
|
||||||
if ( diff1 < 0 ||
|
if ( diff1 < 0 ||
|
||||||
(diff1 == 0 &&
|
(diff1 == 0 &&
|
||||||
|
@ -75,71 +53,31 @@ public:
|
||||||
U_RETURN(true);
|
U_RETURN(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
long diff = (diff1 * 1000L) +
|
ms = (diff1 * 1000L) +
|
||||||
(diff2 / 1000L);
|
(diff2 / 1000L);
|
||||||
|
|
||||||
U_INTERNAL_DUMP("diff = %ld", diff)
|
U_INTERNAL_DUMP("ms = %ld", ms)
|
||||||
|
|
||||||
if (diff <= tolerance) U_RETURN(true);
|
U_ASSERT(checkMilliSecond())
|
||||||
|
|
||||||
U_RETURN(false);
|
U_RETURN(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isOld() const __pure { return isExpired(0); }
|
bool isExpiredWithTolerance() const __pure
|
||||||
bool isExpired() const __pure { return isExpired(UTimeVal::getTolerance()); }
|
|
||||||
|
|
||||||
void setTimerVal(struct timeval* it_value)
|
|
||||||
{
|
{
|
||||||
U_TRACE(0, "UEventTime::setTimerVal(%p)", it_value)
|
U_TRACE_NO_PARAM(0, "UEventTime::isExpiredWithTolerance()")
|
||||||
|
|
||||||
U_CHECK_MEMORY
|
if (isExpired() == false)
|
||||||
|
{
|
||||||
|
U_ASSERT(checkTolerance())
|
||||||
|
|
||||||
it_value->tv_sec = ctime.tv_sec + tv_sec - u_now->tv_sec;
|
if (ms > tolerance) U_RETURN(false);
|
||||||
it_value->tv_usec = ctime.tv_usec + tv_usec - u_now->tv_usec;
|
}
|
||||||
|
|
||||||
UTimeVal::adjust(&(it_value->tv_sec), &(it_value->tv_usec));
|
U_RETURN(true);
|
||||||
|
|
||||||
U_INTERNAL_DUMP("it_value = { %ld %6ld }", it_value->tv_sec, it_value->tv_usec)
|
|
||||||
|
|
||||||
U_INTERNAL_ASSERT(it_value->tv_sec >= 0)
|
|
||||||
U_INTERNAL_ASSERT(it_value->tv_usec >= 0)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
long getTimerVal()
|
time_t expire() const { return (ctime.tv_sec + tv_sec); }
|
||||||
{
|
|
||||||
U_TRACE_NO_PARAM(0, "UEventTime::getTimerVal()")
|
|
||||||
|
|
||||||
U_CHECK_MEMORY
|
|
||||||
|
|
||||||
long ms = ((ctime.tv_sec + tv_sec - u_now->tv_sec) * 1000L) +
|
|
||||||
((ctime.tv_usec + tv_usec - u_now->tv_usec) / 1000L);
|
|
||||||
|
|
||||||
U_RETURN(ms);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct timespec* getTimerValSpec()
|
|
||||||
{
|
|
||||||
U_TRACE_NO_PARAM(0, "UEventTime::getTimerValSpec()")
|
|
||||||
|
|
||||||
U_CHECK_MEMORY
|
|
||||||
|
|
||||||
/**
|
|
||||||
* struct timespec {
|
|
||||||
* time_t tv_sec; // seconds
|
|
||||||
* long tv_nsec; // nanoseconds
|
|
||||||
* };
|
|
||||||
*/
|
|
||||||
|
|
||||||
long ns = ((ctime.tv_sec + tv_sec - u_now->tv_sec) * 1000000000L) +
|
|
||||||
((ctime.tv_usec + tv_usec - u_now->tv_usec) * 1000L);
|
|
||||||
|
|
||||||
timeout.tv_sec = ns / 1000000000L;
|
|
||||||
timeout.tv_nsec = ns % 1000000000L;
|
|
||||||
|
|
||||||
U_INTERNAL_DUMP("timeout = { %ld %9ld }", timeout.tv_sec, timeout.tv_nsec)
|
|
||||||
|
|
||||||
U_RETURN_POINTER(&timeout, struct timespec);
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------
|
// -------------------------------------------
|
||||||
// method VIRTUAL to define
|
// method VIRTUAL to define
|
||||||
|
@ -158,19 +96,162 @@ public:
|
||||||
#ifdef U_STDCPP_ENABLE
|
#ifdef U_STDCPP_ENABLE
|
||||||
friend U_EXPORT ostream& operator<<(ostream& os, const UEventTime& t);
|
friend U_EXPORT ostream& operator<<(ostream& os, const UEventTime& t);
|
||||||
|
|
||||||
# ifdef DEBUG
|
# ifdef DEBUG
|
||||||
const char* dump(bool reset) const;
|
const char* dump(bool reset) const;
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
static struct timespec timeout;
|
long tolerance;
|
||||||
|
|
||||||
|
static long ms;
|
||||||
|
static struct timeval timeout1;
|
||||||
|
static struct timespec timeout2;
|
||||||
|
|
||||||
|
void setCurrentTime()
|
||||||
|
{
|
||||||
|
U_TRACE_NO_PARAM(1, "UEventTime::setCurrentTime()")
|
||||||
|
|
||||||
|
U_CHECK_MEMORY
|
||||||
|
|
||||||
|
(void) U_SYSCALL(gettimeofday, "%p,%p", &ctime, 0);
|
||||||
|
|
||||||
|
U_INTERNAL_DUMP("ctime = { %ld %6ld }", ctime.tv_sec, ctime.tv_usec)
|
||||||
|
}
|
||||||
|
|
||||||
|
void setTime(long timeoutMS)
|
||||||
|
{
|
||||||
|
U_TRACE(0, "UEventTime::setTime(%ld)", timeoutMS)
|
||||||
|
|
||||||
|
setCurrentTime();
|
||||||
|
|
||||||
|
UTimeVal::setMilliSecond(ms = timeoutMS);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setMilliSecond()
|
||||||
|
{
|
||||||
|
U_TRACE_NO_PARAM(0, "UEventTime::setMilliSecond()")
|
||||||
|
|
||||||
|
ms = ((ctime.tv_sec + tv_sec - u_now->tv_sec) * 1000L) +
|
||||||
|
((ctime.tv_usec + tv_usec - u_now->tv_usec) / 1000L);
|
||||||
|
|
||||||
|
U_ASSERT(checkTolerance())
|
||||||
|
}
|
||||||
|
|
||||||
|
bool checkMilliSecond() const
|
||||||
|
{
|
||||||
|
U_TRACE_NO_PARAM(0, "UEventTime::checkMilliSecond()")
|
||||||
|
|
||||||
|
U_INTERNAL_DUMP("ms = %ld", ms)
|
||||||
|
|
||||||
|
long ms_calculated = ((ctime.tv_sec + tv_sec - u_now->tv_sec) * 1000L) +
|
||||||
|
((ctime.tv_usec + tv_usec - u_now->tv_usec) / 1000L);
|
||||||
|
|
||||||
|
if (ms == ms_calculated) U_RETURN(true);
|
||||||
|
|
||||||
|
U_INTERNAL_DUMP("ms_calculated = %ld", ms_calculated)
|
||||||
|
|
||||||
|
U_RETURN(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setTolerance()
|
||||||
|
{
|
||||||
|
U_TRACE_NO_PARAM(0, "UEventTime::setTolerance()")
|
||||||
|
|
||||||
|
tolerance = ((tv_sec * 1000L) +
|
||||||
|
(tv_usec / 1000L)) / 128;
|
||||||
|
|
||||||
|
U_INTERNAL_DUMP("tolerance = %ld", tolerance)
|
||||||
|
}
|
||||||
|
|
||||||
|
bool checkTolerance() const
|
||||||
|
{
|
||||||
|
U_TRACE_NO_PARAM(0, "UEventTime::checkTolerance()")
|
||||||
|
|
||||||
|
U_ASSERT(checkMilliSecond())
|
||||||
|
|
||||||
|
U_INTERNAL_DUMP("tolerance = %ld", tolerance)
|
||||||
|
|
||||||
|
long tolerance_calculated = ((tv_sec * 1000L) +
|
||||||
|
(tv_usec / 1000L)) / 128;
|
||||||
|
|
||||||
|
if (tolerance == tolerance_calculated) U_RETURN(true);
|
||||||
|
|
||||||
|
U_INTERNAL_DUMP("tolerance_calculated = %ld", tolerance_calculated)
|
||||||
|
|
||||||
|
U_RETURN(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static long getMilliSecond(UEventTime* ptimeout)
|
||||||
|
{
|
||||||
|
U_TRACE(0, "UEventTime::getMilliSecond(%p)", ptimeout)
|
||||||
|
|
||||||
|
if (ptimeout == 0) U_RETURN(-1);
|
||||||
|
|
||||||
|
U_ASSERT(ptimeout->checkMilliSecond())
|
||||||
|
|
||||||
|
U_RETURN(ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct timeval* getTimeVal(UEventTime* ptimeout)
|
||||||
|
{
|
||||||
|
U_TRACE(0, "UEventTime::getTimeVal(%p)", ptimeout)
|
||||||
|
|
||||||
|
if (ptimeout == 0) U_RETURN_POINTER(0, struct timeval);
|
||||||
|
|
||||||
|
U_ASSERT(ptimeout->checkMilliSecond())
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct timeval {
|
||||||
|
* long tv_sec; // seconds
|
||||||
|
* long tv_usec; // microseconds
|
||||||
|
* };
|
||||||
|
*/
|
||||||
|
|
||||||
|
long us = ms * 1000L;
|
||||||
|
|
||||||
|
timeout1.tv_sec = us / 1000000L;
|
||||||
|
timeout1.tv_usec = us % 1000000L;
|
||||||
|
|
||||||
|
U_INTERNAL_DUMP("timeout1 = { %ld %9ld }", timeout1.tv_sec, timeout1.tv_usec)
|
||||||
|
|
||||||
|
U_RETURN_POINTER(&timeout1, struct timeval);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct timespec* getTimeSpec(UEventTime* ptimeout)
|
||||||
|
{
|
||||||
|
U_TRACE(0, "UEventTime::getTimeSpec(%p)", ptimeout)
|
||||||
|
|
||||||
|
if (ptimeout == 0) U_RETURN_POINTER(0, struct timespec);
|
||||||
|
|
||||||
|
U_ASSERT(ptimeout->checkMilliSecond())
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct timespec {
|
||||||
|
* time_t tv_sec; // seconds
|
||||||
|
* long tv_nsec; // nanoseconds
|
||||||
|
* };
|
||||||
|
*/
|
||||||
|
|
||||||
|
long ns = ms * 1000000L;
|
||||||
|
|
||||||
|
timeout2.tv_sec = ns / 1000000000L;
|
||||||
|
timeout2.tv_nsec = ns % 1000000000L;
|
||||||
|
|
||||||
|
U_INTERNAL_DUMP("timeout2 = { %ld %9ld }", timeout2.tv_sec, timeout2.tv_nsec)
|
||||||
|
|
||||||
|
U_RETURN_POINTER(&timeout2, struct timespec);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
#ifdef U_COMPILER_DELETE_MEMBERS
|
#ifdef U_COMPILER_DELETE_MEMBERS
|
||||||
UEventTime& operator=(const UEventTime&) = delete;
|
UEventTime& operator=(const UEventTime&) = delete;
|
||||||
#else
|
#else
|
||||||
UEventTime& operator=(const UEventTime&) { return *this; }
|
UEventTime& operator=(const UEventTime&) { return *this; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
friend class UTimer;
|
||||||
|
friend class UNotifier;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -120,7 +120,7 @@ template <class T> inline char* U_OBJECT_TO_TRACE(T& object)
|
||||||
U_INTERNAL_TRACE("U_OBJECT_TO_TRACE(%p)", &object)
|
U_INTERNAL_TRACE("U_OBJECT_TO_TRACE(%p)", &object)
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
bool status = UTrace::suspend();
|
UTrace::suspend();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
char* str = UObject2String<T>(object);
|
char* str = UObject2String<T>(object);
|
||||||
|
@ -128,7 +128,7 @@ template <class T> inline char* U_OBJECT_TO_TRACE(T& object)
|
||||||
str = strndup(str, UObjectIO::buffer_output_len);
|
str = strndup(str, UObjectIO::buffer_output_len);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
UTrace::resume(status);
|
UTrace::resume();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
|
|
|
@ -85,15 +85,15 @@ public:
|
||||||
|
|
||||||
// run the list of timers. Your main program needs to call this every so often, or as indicated by getTimeout()
|
// run the list of timers. Your main program needs to call this every so often, or as indicated by getTimeout()
|
||||||
|
|
||||||
static bool run();
|
static void run();
|
||||||
static void setTimer();
|
static void setTimer();
|
||||||
|
|
||||||
static UEventTime* getTimeout() // returns a timeout indicating how long until the next timer triggers
|
static UEventTime* getTimeout() // returns a timeout indicating how long until the next timer triggers
|
||||||
{
|
{
|
||||||
U_TRACE_NO_PARAM(0, "UTimer::getTimeout()")
|
U_TRACE_NO_PARAM(0, "UTimer::getTimeout()")
|
||||||
|
|
||||||
if (first &&
|
if ( first &&
|
||||||
run())
|
(run(), first))
|
||||||
{
|
{
|
||||||
U_RETURN_POINTER(first->alarm, UEventTime);
|
U_RETURN_POINTER(first->alarm, UEventTime);
|
||||||
}
|
}
|
||||||
|
@ -129,12 +129,12 @@ public:
|
||||||
|
|
||||||
// DEBUG
|
// DEBUG
|
||||||
|
|
||||||
# ifdef DEBUG
|
# ifdef DEBUG
|
||||||
static void printInfo(ostream& os);
|
static void printInfo(ostream& os);
|
||||||
void outputEntry(ostream& os) const U_NO_EXPORT;
|
void outputEntry(ostream& os) const U_NO_EXPORT;
|
||||||
|
|
||||||
const char* dump(bool reset) const;
|
const char* dump(bool reset) const;
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -145,7 +145,7 @@ protected:
|
||||||
static UTimer* pool; // free list
|
static UTimer* pool; // free list
|
||||||
static UTimer* first; // active list
|
static UTimer* first; // active list
|
||||||
|
|
||||||
static bool callHandlerTimeout();
|
static void callHandlerTimeout();
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static bool invariant();
|
static bool invariant();
|
||||||
|
|
|
@ -149,15 +149,6 @@ public:
|
||||||
void setSecond(long sec) { tv_sec = sec; }
|
void setSecond(long sec) { tv_sec = sec; }
|
||||||
void setMicroSecond(long micro_sec) { tv_usec = micro_sec; }
|
void setMicroSecond(long micro_sec) { tv_usec = micro_sec; }
|
||||||
|
|
||||||
void setMilliSecond(long timeoutMS)
|
|
||||||
{
|
|
||||||
U_TRACE(0, "UTimeVal::setMilliSecond(%ld)", timeoutMS)
|
|
||||||
|
|
||||||
tv_usec = timeoutMS * 1000L;
|
|
||||||
|
|
||||||
adjust();
|
|
||||||
}
|
|
||||||
|
|
||||||
long getSecond() const
|
long getSecond() const
|
||||||
{
|
{
|
||||||
U_TRACE_NO_PARAM(0, "UTimeVal::getSecond()")
|
U_TRACE_NO_PARAM(0, "UTimeVal::getSecond()")
|
||||||
|
@ -181,15 +172,6 @@ public:
|
||||||
U_RETURN(ms);
|
U_RETURN(ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
long getTolerance() const
|
|
||||||
{
|
|
||||||
U_TRACE_NO_PARAM(0, "UTimeVal::getTolerance()")
|
|
||||||
|
|
||||||
long ms = getMilliSecond() / 128;
|
|
||||||
|
|
||||||
U_RETURN(ms);
|
|
||||||
}
|
|
||||||
|
|
||||||
double getMicroSecond() const
|
double getMicroSecond() const
|
||||||
{
|
{
|
||||||
U_TRACE_NO_PARAM(0, "UTimeVal::getMicroSecond()")
|
U_TRACE_NO_PARAM(0, "UTimeVal::getMicroSecond()")
|
||||||
|
@ -199,6 +181,18 @@ public:
|
||||||
U_RETURN(micro_sec);
|
U_RETURN(micro_sec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setMilliSecond(long timeoutMS)
|
||||||
|
{
|
||||||
|
U_TRACE(0, "UTimeVal::setMilliSecond(%ld)", timeoutMS)
|
||||||
|
|
||||||
|
tv_sec = 0L;
|
||||||
|
tv_usec = timeoutMS * 1000L;
|
||||||
|
|
||||||
|
adjust();
|
||||||
|
|
||||||
|
U_ASSERT_EQUALS(timeoutMS, getMilliSecond())
|
||||||
|
}
|
||||||
|
|
||||||
// OPERATOR
|
// OPERATOR
|
||||||
|
|
||||||
int operator !() const { return isZero(); }
|
int operator !() const { return isZero(); }
|
||||||
|
|
|
@ -23,7 +23,8 @@
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
static UCrono* time_syscall_read_or_write;
|
int UTrace::status;
|
||||||
|
UCrono* UTrace::time_syscall_read_or_write;
|
||||||
|
|
||||||
U_NO_EXPORT void UTrace::set(int level)
|
U_NO_EXPORT void UTrace::set(int level)
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,13 +17,18 @@
|
||||||
# include <ulib/libevent/event.h>
|
# include <ulib/libevent/event.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct timespec UEventTime::timeout;
|
long UEventTime::ms;
|
||||||
|
struct timeval UEventTime::timeout1;
|
||||||
|
struct timespec UEventTime::timeout2;
|
||||||
|
|
||||||
UEventTime::UEventTime(long sec, long usec) : UTimeVal(sec, usec)
|
UEventTime::UEventTime(long sec, long micro_sec) : UTimeVal(sec, micro_sec)
|
||||||
{
|
{
|
||||||
U_TRACE_REGISTER_OBJECT(0, UEventTime, "%ld,%ld", sec, usec)
|
U_TRACE_REGISTER_OBJECT(0, UEventTime, "%ld,%ld", sec, micro_sec)
|
||||||
|
|
||||||
reset();
|
setTolerance();
|
||||||
|
|
||||||
|
ctime.tv_sec =
|
||||||
|
ctime.tv_usec = 0L;
|
||||||
|
|
||||||
#ifdef USE_LIBEVENT
|
#ifdef USE_LIBEVENT
|
||||||
if (u_ev_base == 0) u_ev_base = (struct event_base*) U_SYSCALL_NO_PARAM(event_init);
|
if (u_ev_base == 0) u_ev_base = (struct event_base*) U_SYSCALL_NO_PARAM(event_init);
|
||||||
|
|
|
@ -22,11 +22,11 @@
|
||||||
# include <sys/event.h>
|
# include <sys/event.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_POLL_H
|
#ifndef HAVE_POLL_H
|
||||||
|
UEventTime* UNotifier::time_obj;
|
||||||
|
#else
|
||||||
# include <poll.h>
|
# include <poll.h>
|
||||||
struct pollfd UNotifier::fds[1];
|
struct pollfd UNotifier::fds[1];
|
||||||
#else
|
|
||||||
UEventTime* UNotifier::time_obj;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -728,37 +728,24 @@ int UNotifier::waitForEvent(int fd_max, fd_set* read_set, fd_set* write_set, UEv
|
||||||
#else
|
#else
|
||||||
int result;
|
int result;
|
||||||
# ifdef HAVE_EPOLL_WAIT
|
# ifdef HAVE_EPOLL_WAIT
|
||||||
int timeoutMS = (ptimeout ? ptimeout->getTimerVal() : -1);
|
result = U_SYSCALL(epoll_wait, "%d,%p,%u,%d", epollfd, events, max_connection, UEventTime::getMilliSecond(ptimeout));
|
||||||
|
|
||||||
result = U_SYSCALL(epoll_wait, "%d,%p,%u,%d", epollfd, events, max_connection, timeoutMS);
|
|
||||||
# elif defined(HAVE_KQUEUE)
|
# elif defined(HAVE_KQUEUE)
|
||||||
struct timespec* timeout = (ptimeout ? ptimeout->getTimerValSpec() : 0);
|
result = U_SYSCALL(kevent, "%d,%p,%d,%p,%d,%p", kq, kqevents, nkqevents, kqrevents, max_connection, UEventTime::getTimeSpec(ptimeout));
|
||||||
|
|
||||||
result = U_SYSCALL(kevent, "%d,%p,%d,%p,%d,%p", kq, kqevents, nkqevents, kqrevents, max_connection, timeout);
|
|
||||||
nkqevents = 0;
|
nkqevents = 0;
|
||||||
# else
|
# else
|
||||||
static struct timeval tmp;
|
// If both fields of the timeval structure are zero, then select() returns immediately.
|
||||||
struct timeval* ptmp;
|
// (This is useful for polling). If ptimeout is NULL (no timeout), select() can block indefinitely...
|
||||||
|
//
|
||||||
|
// On Linux, the function select modifies timeout to reflect the amount of time not slept; most other implementations do not do this.
|
||||||
|
// This causes problems both when Linux code which reads timeout is ported to other operating systems, and when code is ported to Linux
|
||||||
|
// that reuses a struct timeval for multiple selects in a loop without reinitializing it. Consider timeout to be undefined after select returns
|
||||||
|
|
||||||
# if defined(DEBUG) && !defined(_MSWINDOWS_)
|
# if defined(DEBUG) && !defined(_MSWINDOWS_)
|
||||||
if ( read_set) U_INTERNAL_DUMP(" read_set = %B", __FDS_BITS( read_set)[0])
|
if ( read_set) U_INTERNAL_DUMP(" read_set = %B", __FDS_BITS( read_set)[0])
|
||||||
if (write_set) U_INTERNAL_DUMP("write_set = %B", __FDS_BITS(write_set)[0])
|
if (write_set) U_INTERNAL_DUMP("write_set = %B", __FDS_BITS(write_set)[0])
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
if (ptimeout == 0) ptmp = 0;
|
result = U_SYSCALL(select, "%d,%p,%p,%p,%p", fd_max, read_set, write_set, 0, UEventTime::getTimeVal(ptimeout));
|
||||||
else
|
|
||||||
{
|
|
||||||
// On Linux, the function select modifies timeout to reflect the amount of time not slept; most other implementations do not do this.
|
|
||||||
// This causes problems both when Linux code which reads timeout is ported to other operating systems, and when code is ported to Linux
|
|
||||||
// that reuses a struct timeval for multiple selects in a loop without reinitializing it. Consider timeout to be undefined after select returns
|
|
||||||
|
|
||||||
ptimeout->setTimerVal(ptmp = &tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If both fields of the timeval structure are zero, then select() returns immediately.
|
|
||||||
// (This is useful for polling). If ptmp is NULL (no timeout), select() can block indefinitely...
|
|
||||||
|
|
||||||
result = U_SYSCALL(select, "%d,%p,%p,%p,%p", fd_max, read_set, write_set, 0, ptmp);
|
|
||||||
|
|
||||||
# if defined(DEBUG) && !defined(_MSWINDOWS_)
|
# if defined(DEBUG) && !defined(_MSWINDOWS_)
|
||||||
if ( read_set) U_INTERNAL_DUMP(" read_set = %B", __FDS_BITS( read_set)[0])
|
if ( read_set) U_INTERNAL_DUMP(" read_set = %B", __FDS_BITS( read_set)[0])
|
||||||
|
@ -793,9 +780,7 @@ loop:
|
||||||
ptimeout);
|
ptimeout);
|
||||||
# elif defined(HAVE_KQUEUE)
|
# elif defined(HAVE_KQUEUE)
|
||||||
loop:
|
loop:
|
||||||
struct timespec* timeout = (ptimeout ? ptimeout->getTimerValSpec() : 0);
|
nfd_ready = U_SYSCALL(kevent, "%d,%p,%d,%p,%d,%p", kq, kqevents, nkqevents, kqrevents, max_connection, UEventTime::getTimeSpec(ptimeout));
|
||||||
|
|
||||||
nfd_ready = U_SYSCALL(kevent, "%d,%p,%d,%p,%d,%p", kq, kqevents, nkqevents, kqrevents, max_connection, timeout);
|
|
||||||
# ifdef DEBUG
|
# ifdef DEBUG
|
||||||
if (nfd_ready == -1 &&
|
if (nfd_ready == -1 &&
|
||||||
errno == EINVAL)
|
errno == EINVAL)
|
||||||
|
@ -806,9 +791,7 @@ loop:
|
||||||
nkqevents = 0;
|
nkqevents = 0;
|
||||||
# else
|
# else
|
||||||
loop:
|
loop:
|
||||||
int timeoutMS = (ptimeout ? ptimeout->getTimerVal() : -1);
|
nfd_ready = U_SYSCALL(epoll_wait, "%d,%p,%u,%d", epollfd, events, max_connection, UEventTime::getMilliSecond(ptimeout));
|
||||||
|
|
||||||
nfd_ready = U_SYSCALL(epoll_wait, "%d,%p,%u,%d", epollfd, events, max_connection, timeoutMS);
|
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
if (nfd_ready > 0)
|
if (nfd_ready > 0)
|
||||||
|
@ -1045,11 +1028,11 @@ loop:
|
||||||
waitForEvent(ptimeout = UTimer::getTimeout());
|
waitForEvent(ptimeout = UTimer::getTimeout());
|
||||||
|
|
||||||
if (nfd_ready == 0 &&
|
if (nfd_ready == 0 &&
|
||||||
ptimeout)
|
ptimeout != 0)
|
||||||
{
|
{
|
||||||
U_INTERNAL_ASSERT_EQUALS(UTimer::first->alarm, ptimeout)
|
U_INTERNAL_ASSERT_EQUALS(UTimer::first->alarm, ptimeout)
|
||||||
|
|
||||||
(void) UTimer::callHandlerTimeout();
|
UTimer::callHandlerTimeout();
|
||||||
|
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
|
@ -1322,7 +1305,7 @@ int UNotifier::waitForRead(int fd, int timeoutMS)
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
// If both fields of the timeval structure are zero, then select() returns immediately.
|
// If both fields of the timeval structure are zero, then select() returns immediately.
|
||||||
// (This is useful for polling). If ptmp is NULL (no timeout), select() can block indefinitely...
|
// (This is useful for polling). If ptime is NULL (no timeout), select() can block indefinitely...
|
||||||
|
|
||||||
UEventTime* ptime;
|
UEventTime* ptime;
|
||||||
|
|
||||||
|
@ -1377,9 +1360,9 @@ int UNotifier::waitForWrite(int fd, int timeoutMS)
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
||||||
# ifdef _MSWINDOWS_
|
# ifdef _MSWINDOWS_
|
||||||
if (is_pipe(fd) != INVALID_HANDLE_VALUE) U_RETURN(1);
|
if (is_pipe(fd) != INVALID_HANDLE_VALUE) U_RETURN(1);
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
// If both fields of the timeval structure are zero, then select() returns immediately.
|
// If both fields of the timeval structure are zero, then select() returns immediately.
|
||||||
// (This is useful for polling). If ptmp is NULL (no timeout), select() can block indefinitely...
|
// (This is useful for polling). If ptmp is NULL (no timeout), select() can block indefinitely...
|
||||||
|
|
|
@ -41,7 +41,7 @@ void UTimer::init(Type _mode)
|
||||||
|
|
||||||
U_NO_EXPORT void UTimer::insertEntry()
|
U_NO_EXPORT void UTimer::insertEntry()
|
||||||
{
|
{
|
||||||
U_TRACE_NO_PARAM(1, "UTimer::insertEntry()")
|
U_TRACE_NO_PARAM(0, "UTimer::insertEntry()")
|
||||||
|
|
||||||
U_CHECK_MEMORY
|
U_CHECK_MEMORY
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ U_NO_EXPORT void UTimer::insertEntry()
|
||||||
U_ASSERT(invariant())
|
U_ASSERT(invariant())
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UTimer::callHandlerTimeout()
|
void UTimer::callHandlerTimeout()
|
||||||
{
|
{
|
||||||
U_TRACE_NO_PARAM(0, "UTimer::callHandlerTimeout()")
|
U_TRACE_NO_PARAM(0, "UTimer::callHandlerTimeout()")
|
||||||
|
|
||||||
|
@ -87,73 +87,83 @@ bool UTimer::callHandlerTimeout()
|
||||||
|
|
||||||
item->insertEntry();
|
item->insertEntry();
|
||||||
|
|
||||||
U_RETURN(true);
|
item->alarm->setMilliSecond();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// put it on the free list
|
||||||
|
|
||||||
// put it on the free list
|
item->alarm = 0;
|
||||||
|
item->next = pool;
|
||||||
item->alarm = 0;
|
pool = item;
|
||||||
item->next = pool;
|
}
|
||||||
pool = item;
|
|
||||||
|
|
||||||
U_RETURN(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UTimer::run()
|
void UTimer::run()
|
||||||
{
|
{
|
||||||
U_TRACE_NO_PARAM(1, "UTimer::run()")
|
U_TRACE_NO_PARAM(1, "UTimer::run()")
|
||||||
|
|
||||||
U_INTERNAL_ASSERT_POINTER(first)
|
|
||||||
|
|
||||||
(void) U_SYSCALL(gettimeofday, "%p,%p", u_now, 0);
|
(void) U_SYSCALL(gettimeofday, "%p,%p", u_now, 0);
|
||||||
|
|
||||||
U_INTERNAL_DUMP("u_now = { %ld %6ld }", u_now->tv_sec, u_now->tv_usec)
|
U_INTERNAL_DUMP("u_now = { %ld %6ld } first = %p", u_now->tv_sec, u_now->tv_usec, first)
|
||||||
|
|
||||||
|
UTimer* item = first;
|
||||||
|
bool bnosignal = (mode == NOSIGNAL), bexpired;
|
||||||
|
|
||||||
loop:
|
loop:
|
||||||
if ((mode == NOSIGNAL ? first->alarm->isOld()
|
#ifdef DEBUG
|
||||||
: first->alarm->isExpired()))
|
U_INTERNAL_DUMP("item = %p item->next = %p", item, item->next)
|
||||||
{
|
|
||||||
if (callHandlerTimeout() ||
|
|
||||||
first)
|
|
||||||
{
|
|
||||||
goto loop;
|
|
||||||
}
|
|
||||||
|
|
||||||
U_RETURN(false);
|
U_INTERNAL_ASSERT_POINTER(item)
|
||||||
|
|
||||||
|
if (item->next) U_INTERNAL_ASSERT(*item <= *(item->next))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bexpired = (bnosignal ? item->alarm->isExpired()
|
||||||
|
: item->alarm->isExpiredWithTolerance());
|
||||||
|
|
||||||
|
if (bexpired)
|
||||||
|
{
|
||||||
|
item = item->next;
|
||||||
|
|
||||||
|
callHandlerTimeout();
|
||||||
|
|
||||||
|
if (item) goto loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
U_INTERNAL_DUMP("first = %p", first)
|
U_INTERNAL_DUMP("first = %p", first)
|
||||||
|
|
||||||
if (first) U_RETURN(true);
|
|
||||||
|
|
||||||
U_RETURN(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UTimer::setTimer()
|
void UTimer::setTimer()
|
||||||
{
|
{
|
||||||
U_TRACE_NO_PARAM(1, "UTimer::setTimer()")
|
U_TRACE_NO_PARAM(1, "UTimer::setTimer()")
|
||||||
|
|
||||||
U_INTERNAL_ASSERT_POINTER(first)
|
|
||||||
U_INTERNAL_ASSERT_DIFFERS(mode, NOSIGNAL)
|
U_INTERNAL_ASSERT_DIFFERS(mode, NOSIGNAL)
|
||||||
|
|
||||||
if (run())
|
run();
|
||||||
{
|
|
||||||
U_INTERNAL_ASSERT_POINTER(first)
|
|
||||||
|
|
||||||
first->alarm->setTimerVal(&UInterrupt::timerval.it_value);
|
if (first == 0)
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
U_INTERNAL_ASSERT_EQUALS(first, 0)
|
|
||||||
|
|
||||||
UInterrupt::timerval.it_value.tv_sec =
|
UInterrupt::timerval.it_value.tv_sec =
|
||||||
UInterrupt::timerval.it_value.tv_usec = 0L;
|
UInterrupt::timerval.it_value.tv_usec = 0L;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UEventTime* item = first->alarm;
|
||||||
|
|
||||||
// NB: can happen that setitimer() produce immediatly a signal because the interval is very short (< 10ms)...
|
UInterrupt::timerval.it_value.tv_sec = item->ctime.tv_sec + item->tv_sec - u_now->tv_sec;
|
||||||
|
UInterrupt::timerval.it_value.tv_usec = item->ctime.tv_usec + item->tv_usec - u_now->tv_usec;
|
||||||
|
|
||||||
|
UTimeVal::adjust(&(UInterrupt::timerval.it_value.tv_sec), &(UInterrupt::timerval.it_value.tv_usec));
|
||||||
|
}
|
||||||
|
|
||||||
|
// NB: it can happen that setitimer() produce immediatly a signal because the interval is very short (< 10ms)...
|
||||||
|
|
||||||
U_INTERNAL_DUMP("UInterrupt::timerval.it_value = { %ld %6ld }", UInterrupt::timerval.it_value.tv_sec, UInterrupt::timerval.it_value.tv_usec)
|
U_INTERNAL_DUMP("UInterrupt::timerval.it_value = { %ld %6ld }", UInterrupt::timerval.it_value.tv_sec, UInterrupt::timerval.it_value.tv_usec)
|
||||||
|
|
||||||
|
U_INTERNAL_ASSERT(UInterrupt::timerval.it_value.tv_sec >= 0 &&
|
||||||
|
UInterrupt::timerval.it_value.tv_usec >= 0)
|
||||||
|
|
||||||
(void) U_SYSCALL(setitimer, "%d,%p,%p", ITIMER_REAL, &UInterrupt::timerval, 0);
|
(void) U_SYSCALL(setitimer, "%d,%p,%p", ITIMER_REAL, &UInterrupt::timerval, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,7 +171,7 @@ void UTimer::insert(UEventTime* a)
|
||||||
{
|
{
|
||||||
U_TRACE(0, "UTimer::insert(%p,%b)", a)
|
U_TRACE(0, "UTimer::insert(%p,%b)", a)
|
||||||
|
|
||||||
// set an alarm to more than 2 month is very strange...
|
// set an alarm to more than 2 month is very suspect...
|
||||||
|
|
||||||
U_INTERNAL_ASSERT_MINOR(a->tv_sec, 60L * U_ONE_DAY_IN_SECOND) // 60 gg (2 month)
|
U_INTERNAL_ASSERT_MINOR(a->tv_sec, 60L * U_ONE_DAY_IN_SECOND) // 60 gg (2 month)
|
||||||
|
|
||||||
|
@ -210,14 +220,14 @@ void UTimer::erase(UEventTime* a)
|
||||||
|
|
||||||
void UTimer::clear()
|
void UTimer::clear()
|
||||||
{
|
{
|
||||||
U_TRACE_NO_PARAM(0, "UTimer::clear()")
|
U_TRACE_NO_PARAM(1, "UTimer::clear()")
|
||||||
|
|
||||||
U_INTERNAL_DUMP("mode = %d first = %p pool = %p", mode, first, pool)
|
U_INTERNAL_DUMP("mode = %d first = %p pool = %p", mode, first, pool)
|
||||||
|
|
||||||
if (mode != NOSIGNAL)
|
if (mode != NOSIGNAL)
|
||||||
{
|
{
|
||||||
UInterrupt::timerval.it_value.tv_sec =
|
UInterrupt::timerval.it_value.tv_sec =
|
||||||
UInterrupt::timerval.it_value.tv_usec = 0;
|
UInterrupt::timerval.it_value.tv_usec = 0L;
|
||||||
|
|
||||||
(void) U_SYSCALL(setitimer, "%d,%p,%p", ITIMER_REAL, &UInterrupt::timerval, 0);
|
(void) U_SYSCALL(setitimer, "%d,%p,%p", ITIMER_REAL, &UInterrupt::timerval, 0);
|
||||||
}
|
}
|
||||||
|
@ -252,7 +262,7 @@ bool UTimer::invariant()
|
||||||
{
|
{
|
||||||
for (UTimer* item = first; item->next; item = item->next)
|
for (UTimer* item = first; item->next; item = item->next)
|
||||||
{
|
{
|
||||||
U_INTERNAL_ASSERT(*item <= *(item->next))
|
if (item->next) U_INTERNAL_ASSERT(*item <= *(item->next))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ HTTP/1.1 200 OK
|
||||||
Date: Thu, 03 Jul 2014 10:11:10 GMT
|
Date: Thu, 03 Jul 2014 10:11:10 GMT
|
||||||
Server: ULib
|
Server: ULib
|
||||||
Content-Length: 27
|
Content-Length: 27
|
||||||
Content-Type: application/json; charset=UTF-8
|
Content-Type: application/json
|
||||||
|
|
||||||
{"message":"Hello, World!"}
|
{"message":"Hello, World!"}
|
||||||
```
|
```
|
||||||
|
@ -57,7 +57,7 @@ HTTP/1.1 200 OK
|
||||||
Date: Thu, 03 Jul 2014 10:14:51 GMT
|
Date: Thu, 03 Jul 2014 10:14:51 GMT
|
||||||
Server: ULib
|
Server: ULib
|
||||||
Content-Length: 31
|
Content-Length: 31
|
||||||
Content-Type: application/json; charset=UTF-8
|
Content-Type: application/json
|
||||||
|
|
||||||
{"id":6227,"randomNumber":8489}
|
{"id":6227,"randomNumber":8489}
|
||||||
```
|
```
|
||||||
|
@ -69,7 +69,7 @@ HTTP/1.1 200 OK
|
||||||
Date: Thu, 03 Jul 2014 10:14:51 GMT
|
Date: Thu, 03 Jul 2014 10:14:51 GMT
|
||||||
Server: ULib
|
Server: ULib
|
||||||
Content-Length: 320
|
Content-Length: 320
|
||||||
Content-Type: application/json; charset=UTF-8
|
Content-Type: application/json
|
||||||
|
|
||||||
[{"id":6851,"randomNumber":7598},{"id":3968,"randomNumber":7325},{"id":8159,"randomNumber":348},{"id":9560,"randomNumber":7333},{"id":9938,"randomNumber":9080},{"id":1598,"randomNumber":1623},{"id":3280,"randomNumber":8707},{"id":4521,"randomNumber":6063},{"id":8173,"randomNumber":3690},{"id":3648,"randomNumber":8803}]
|
[{"id":6851,"randomNumber":7598},{"id":3968,"randomNumber":7325},{"id":8159,"randomNumber":348},{"id":9560,"randomNumber":7333},{"id":9938,"randomNumber":9080},{"id":1598,"randomNumber":1623},{"id":3280,"randomNumber":8707},{"id":4521,"randomNumber":6063},{"id":8173,"randomNumber":3690},{"id":3648,"randomNumber":8803}]
|
||||||
```
|
```
|
||||||
|
@ -80,7 +80,7 @@ Content-Type: application/json; charset=UTF-8
|
||||||
HTTP/1.1 200 OK
|
HTTP/1.1 200 OK
|
||||||
Date: Thu, 03 Jul 2014 10:14:51 GMT
|
Date: Thu, 03 Jul 2014 10:14:51 GMT
|
||||||
Server: ULib
|
Server: ULib
|
||||||
Content-Type: text/html; charset=UTF-8
|
Content-Type: text/html
|
||||||
Content-Length: 1227
|
Content-Length: 1227
|
||||||
|
|
||||||
<!doctype html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr><tr><td>11</td><td><script>alert("This should not be displayed in a browser alert box.");</script></td></tr><tr><td>4</td><td>A bad random number generator: 1, 1, 1, 1, 1, 4.33e+67, 1, 1, 1</td></tr><tr><td>5</td><td>A computer program does what you tell it to do, not what you want it to do.</td></tr><tr><td>2</td><td>A computer scientist is someone who fixes things that aren't broken.</td></tr><tr><td>8</td><td>A list is only as strong as its weakest link. — Donald Knuth</td></tr><tr><td>0</td><td>Additional fortune added at request time.</td></tr><tr><td>3</td><td>After enough decimal places, nobody gives a damn.</td></tr><tr><td>7</td><td>Any program that runs right is obsolete.</td></tr><tr><td>10</td><td>Computers make very fast, very accurate mistakes.</td></tr><tr><td>6</td><td>Emacs is a nice operating system, but I prefer UNIX. — Tom Christaensen</td></tr><tr><td>9</td><td>Feature: A bug with seniority.</td></tr><tr><td>1</td><td>fortune: No such file or directory</td></tr><tr><td>12</td><td>フレームワークのベンチマーク</td></tr></table></body></html>
|
<!doctype html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr><tr><td>11</td><td><script>alert("This should not be displayed in a browser alert box.");</script></td></tr><tr><td>4</td><td>A bad random number generator: 1, 1, 1, 1, 1, 4.33e+67, 1, 1, 1</td></tr><tr><td>5</td><td>A computer program does what you tell it to do, not what you want it to do.</td></tr><tr><td>2</td><td>A computer scientist is someone who fixes things that aren't broken.</td></tr><tr><td>8</td><td>A list is only as strong as its weakest link. — Donald Knuth</td></tr><tr><td>0</td><td>Additional fortune added at request time.</td></tr><tr><td>3</td><td>After enough decimal places, nobody gives a damn.</td></tr><tr><td>7</td><td>Any program that runs right is obsolete.</td></tr><tr><td>10</td><td>Computers make very fast, very accurate mistakes.</td></tr><tr><td>6</td><td>Emacs is a nice operating system, but I prefer UNIX. — Tom Christaensen</td></tr><tr><td>9</td><td>Feature: A bug with seniority.</td></tr><tr><td>1</td><td>fortune: No such file or directory</td></tr><tr><td>12</td><td>フレームワークのベンチマーク</td></tr></table></body></html>
|
||||||
|
@ -93,7 +93,7 @@ HTTP/1.1 200 OK
|
||||||
Date: Thu, 03 Jul 2014 10:14:51 GMT
|
Date: Thu, 03 Jul 2014 10:14:51 GMT
|
||||||
Server: ULib
|
Server: ULib
|
||||||
Content-Length: 319
|
Content-Length: 319
|
||||||
Content-Type: application/json; charset=UTF-8
|
Content-Type: application/json
|
||||||
|
|
||||||
[{"id":7171,"randomNumber":351},{"id":6019,"randomNumber":9725},{"id":8118,"randomNumber":4023},{"id":7965,"randomNumber":1388},{"id":7797,"randomNumber":2249},{"id":112,"randomNumber":1108},{"id":6127,"randomNumber":4323},{"id":2597,"randomNumber":7509},{"id":2978,"randomNumber":7883},{"id":1111,"randomNumber":2228}]
|
[{"id":7171,"randomNumber":351},{"id":6019,"randomNumber":9725},{"id":8118,"randomNumber":4023},{"id":7965,"randomNumber":1388},{"id":7797,"randomNumber":2249},{"id":112,"randomNumber":1108},{"id":6127,"randomNumber":4323},{"id":2597,"randomNumber":7509},{"id":2978,"randomNumber":7883},{"id":1111,"randomNumber":2228}]
|
||||||
```
|
```
|
||||||
|
@ -104,7 +104,7 @@ Content-Type: application/json; charset=UTF-8
|
||||||
HTTP/1.1 200 OK
|
HTTP/1.1 200 OK
|
||||||
Date: Thu, 03 Jul 2014 10:14:51 GMT
|
Date: Thu, 03 Jul 2014 10:14:51 GMT
|
||||||
Server: ULib
|
Server: ULib
|
||||||
Content-Type: text/plain; charset=UTF-8
|
Content-Type: text/plain
|
||||||
Content-Length: 13
|
Content-Length: 13
|
||||||
|
|
||||||
Hello, World!
|
Hello, World!
|
||||||
|
|
|
@ -7,9 +7,10 @@
|
||||||
start_msg tsa_rpc
|
start_msg tsa_rpc
|
||||||
|
|
||||||
#UTRACE="0 50M 0"
|
#UTRACE="0 50M 0"
|
||||||
|
#UTRACE_SIGNAL="0 10M -1"
|
||||||
#UOBJDUMP="0 1M 100"
|
#UOBJDUMP="0 1M 100"
|
||||||
#USIMERR="error.sim"
|
#USIMERR="error.sim"
|
||||||
export UTRACE UOBJDUMP USIMERR
|
export UTRACE UOBJDUMP USIMERR UTRACE_SIGNAL
|
||||||
|
|
||||||
DOC_ROOT=TSA
|
DOC_ROOT=TSA
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
|
|
||||||
#define TEST_CHANGE(b) {if(!TestChange(b))return 1;}
|
#define TEST_CHANGE(b) {if(!TestChange(b))return 1;}
|
||||||
|
|
||||||
static bool status;
|
|
||||||
static volatile int n;
|
static volatile int n;
|
||||||
static int time_to_sleep = 5;
|
static int time_to_sleep = 5;
|
||||||
|
|
||||||
|
@ -83,7 +82,7 @@ public:
|
||||||
if (WaitNValue(2)) // wait for main thread
|
if (WaitNValue(2)) // wait for main thread
|
||||||
{
|
{
|
||||||
# ifdef DEBUG
|
# ifdef DEBUG
|
||||||
status = UTrace::suspend();
|
UTrace::suspend();
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
|
@ -261,7 +260,7 @@ int U_EXPORT main(int argc, char* argv[])
|
||||||
time_to_sleep = 5000;
|
time_to_sleep = 5000;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
UTrace::resume(status);
|
UTrace::resume();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Test child thread destroying before father
|
// Test child thread destroying before father
|
||||||
|
|
Loading…
Reference in New Issue
Block a user