server: Change the timeout handling to use NT-style 64-bit timeouts everywhere.
This commit is contained in:
parent
31368dec93
commit
aaf477f292
|
@ -1301,7 +1301,10 @@ BOOL WINAPI WaitNamedPipeW (LPCWSTR name, DWORD nTimeOut)
|
|||
}
|
||||
|
||||
pipe_wait->TimeoutSpecified = !(nTimeOut == NMPWAIT_USE_DEFAULT_WAIT);
|
||||
pipe_wait->Timeout.QuadPart = (ULONGLONG)nTimeOut * -10000;
|
||||
if (nTimeOut == NMPWAIT_WAIT_FOREVER)
|
||||
pipe_wait->Timeout.QuadPart = ((ULONGLONG)0x7fffffff << 32) | 0xffffffff;
|
||||
else
|
||||
pipe_wait->Timeout.QuadPart = (ULONGLONG)nTimeOut * -10000;
|
||||
pipe_wait->NameLength = nt_name.Length - sizeof(leadin);
|
||||
memcpy(pipe_wait->Name, nt_name.Buffer + sizeof(leadin)/sizeof(WCHAR),
|
||||
pipe_wait->NameLength);
|
||||
|
@ -1771,8 +1774,12 @@ BOOL WINAPI GetMailslotInfo( HANDLE hMailslot, LPDWORD lpMaxMessageSize,
|
|||
if( lpMessageCount )
|
||||
*lpMessageCount = info.MessagesAvailable;
|
||||
if( lpReadTimeout )
|
||||
*lpReadTimeout = info.ReadTimeout.QuadPart / -10000;
|
||||
|
||||
{
|
||||
if (info.ReadTimeout.QuadPart == (((LONGLONG)0x7fffffff << 32) | 0xffffffff))
|
||||
*lpReadTimeout = MAILSLOT_WAIT_FOREVER;
|
||||
else
|
||||
*lpReadTimeout = info.ReadTimeout.QuadPart / -10000;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -1798,7 +1805,10 @@ BOOL WINAPI SetMailslotInfo( HANDLE hMailslot, DWORD dwReadTimeout)
|
|||
|
||||
TRACE("%p %d\n", hMailslot, dwReadTimeout);
|
||||
|
||||
info.ReadTimeout.QuadPart = dwReadTimeout * -10000;
|
||||
if (dwReadTimeout != MAILSLOT_WAIT_FOREVER)
|
||||
info.ReadTimeout.QuadPart = (ULONGLONG)dwReadTimeout * -10000;
|
||||
else
|
||||
info.ReadTimeout.QuadPart = ((LONGLONG)0x7fffffff << 32) | 0xffffffff;
|
||||
status = NtSetInformationFile( hMailslot, &iosb, &info, sizeof info,
|
||||
FileMailslotSetInformation );
|
||||
if( status != STATUS_SUCCESS )
|
||||
|
|
|
@ -430,7 +430,9 @@ static NTSTATUS get_io_timeouts( HANDLE handle, enum server_fd_type type, ULONG
|
|||
{
|
||||
req->handle = handle;
|
||||
req->flags = 0;
|
||||
if (!(status = wine_server_call( req ))) timeouts->total = reply->read_timeout;
|
||||
if (!(status = wine_server_call( req )) &&
|
||||
reply->read_timeout != TIMEOUT_INFINITE)
|
||||
timeouts->total = reply->read_timeout / -10000;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
}
|
||||
|
@ -1113,8 +1115,7 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
|
|||
SERVER_START_REQ(wait_named_pipe)
|
||||
{
|
||||
req->handle = handle;
|
||||
req->timeout = buff->TimeoutSpecified ? buff->Timeout.QuadPart / -10000L
|
||||
: NMPWAIT_USE_DEFAULT_WAIT;
|
||||
req->timeout = buff->TimeoutSpecified ? buff->Timeout.QuadPart : 0;
|
||||
req->async.callback = pipe_completion_wait;
|
||||
req->async.iosb = io;
|
||||
req->async.arg = NULL;
|
||||
|
@ -1467,7 +1468,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
|
|||
info->MailslotQuota = 0;
|
||||
info->NextMessageSize = 0;
|
||||
info->MessagesAvailable = 0;
|
||||
info->ReadTimeout.QuadPart = reply->read_timeout * -10000;
|
||||
info->ReadTimeout.QuadPart = reply->read_timeout;
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
@ -1660,7 +1661,7 @@ NTSTATUS WINAPI NtSetInformationFile(HANDLE handle, PIO_STATUS_BLOCK io,
|
|||
{
|
||||
req->handle = handle;
|
||||
req->flags = MAILSLOT_SET_READ_TIMEOUT;
|
||||
req->read_timeout = info->ReadTimeout.QuadPart / -10000;
|
||||
req->read_timeout = info->ReadTimeout.QuadPart;
|
||||
io->u.Status = wine_server_call( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
@ -2186,8 +2187,8 @@ NTSTATUS WINAPI NtCreateNamedPipeFile( PHANDLE handle, ULONG access,
|
|||
options, pipe_type, read_mode, completion_mode, max_inst, inbound_quota,
|
||||
outbound_quota, timeout);
|
||||
|
||||
/* assume we only get relative timeout, and storable in a DWORD as ms */
|
||||
if (timeout->QuadPart > 0 || (timeout->QuadPart / -10000) >> 32)
|
||||
/* assume we only get relative timeout */
|
||||
if (timeout->QuadPart > 0)
|
||||
FIXME("Wrong time %s\n", wine_dbgstr_longlong(timeout->QuadPart));
|
||||
|
||||
SERVER_START_REQ( create_named_pipe )
|
||||
|
@ -2203,7 +2204,7 @@ NTSTATUS WINAPI NtCreateNamedPipeFile( PHANDLE handle, ULONG access,
|
|||
req->maxinstances = max_inst;
|
||||
req->outsize = outbound_quota;
|
||||
req->insize = inbound_quota;
|
||||
req->timeout = timeout->QuadPart / -10000;
|
||||
req->timeout = timeout->QuadPart;
|
||||
wine_server_add_data( req, attr->ObjectName->Buffer,
|
||||
attr->ObjectName->Length );
|
||||
status = wine_server_call( req );
|
||||
|
@ -2306,7 +2307,7 @@ NTSTATUS WINAPI NtCreateMailslotFile(PHANDLE pHandle, ULONG DesiredAccess,
|
|||
req->attributes = attr->Attributes;
|
||||
req->rootdir = attr->RootDirectory;
|
||||
req->max_msgsize = MaxMessageSize;
|
||||
req->read_timeout = (timeout.QuadPart <= 0) ? timeout.QuadPart / -10000 : -1;
|
||||
req->read_timeout = timeout.QuadPart;
|
||||
wine_server_add_data( req, attr->ObjectName->Buffer,
|
||||
attr->ObjectName->Length );
|
||||
ret = wine_server_call( req );
|
||||
|
|
|
@ -696,7 +696,7 @@ NTSTATUS WINAPI NtQuerySystemInformation(
|
|||
memset(&sti, 0 , sizeof(sti));
|
||||
|
||||
/* liKeSystemTime, liExpTimeZoneBias, uCurrentTimeZoneId */
|
||||
NTDLL_from_server_abstime( &sti.liKeBootTime, &server_start_time );
|
||||
sti.liKeBootTime.QuadPart = server_start_time;
|
||||
|
||||
if (Length <= sizeof(sti))
|
||||
{
|
||||
|
|
|
@ -40,8 +40,6 @@ extern void set_cpu_context( const CONTEXT *context );
|
|||
extern LPCSTR debugstr_us( const UNICODE_STRING *str );
|
||||
extern void dump_ObjectAttributes (const OBJECT_ATTRIBUTES *ObjectAttributes);
|
||||
|
||||
extern void NTDLL_get_server_abstime( abs_time_t *when, const LARGE_INTEGER *timeout );
|
||||
extern void NTDLL_from_server_abstime( LARGE_INTEGER *time, const abs_time_t *when );
|
||||
extern NTSTATUS NTDLL_queue_process_apc( HANDLE process, const apc_call_t *call, apc_result_t *result );
|
||||
extern NTSTATUS NTDLL_wait_for_multiple_objects( UINT count, const HANDLE *handles, UINT flags,
|
||||
const LARGE_INTEGER *timeout, HANDLE signal_object );
|
||||
|
@ -56,7 +54,7 @@ extern void virtual_init(void);
|
|||
extern void virtual_init_threading(void);
|
||||
|
||||
/* server support */
|
||||
extern abs_time_t server_start_time;
|
||||
extern timeout_t server_start_time;
|
||||
extern void server_init_process(void);
|
||||
extern NTSTATUS server_init_process_done(void);
|
||||
extern size_t server_init_thread( int unix_pid, int unix_tid, void *entry_point );
|
||||
|
|
|
@ -236,8 +236,8 @@ NTSTATUS WINAPI NtQueryInformationProcess(
|
|||
req->handle = ProcessHandle;
|
||||
if ((ret = wine_server_call( req )) == STATUS_SUCCESS)
|
||||
{
|
||||
NTDLL_from_server_abstime(&pti.CreateTime, &reply->start_time);
|
||||
NTDLL_from_server_abstime(&pti.ExitTime, &reply->end_time);
|
||||
pti.CreateTime.QuadPart = reply->start_time;
|
||||
pti.ExitTime.QuadPart = reply->end_time;
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
|
|
@ -85,7 +85,7 @@ struct cmsg_fd
|
|||
};
|
||||
#endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
|
||||
|
||||
abs_time_t server_start_time = { 0, 0 }; /* time of server startup */
|
||||
timeout_t server_start_time = 0; /* time of server startup */
|
||||
|
||||
extern struct wine_pthread_functions pthread_functions;
|
||||
|
||||
|
|
|
@ -478,16 +478,9 @@ NTSTATUS WINAPI NtSetTimer(IN HANDLE handle,
|
|||
|
||||
SERVER_START_REQ( set_timer )
|
||||
{
|
||||
if (!when->u.LowPart && !when->u.HighPart)
|
||||
{
|
||||
/* special case to start timeout on now+period without too many calculations */
|
||||
req->expire.sec = 0;
|
||||
req->expire.usec = 0;
|
||||
}
|
||||
else NTDLL_get_server_abstime( &req->expire, when );
|
||||
|
||||
req->handle = handle;
|
||||
req->period = period;
|
||||
req->expire = when->QuadPart;
|
||||
req->callback = callback;
|
||||
req->arg = callback_arg;
|
||||
status = wine_server_call( req );
|
||||
|
@ -564,7 +557,7 @@ NTSTATUS WINAPI NtQueryTimer(
|
|||
status = wine_server_call(req);
|
||||
|
||||
/* convert server time to absolute NTDLL time */
|
||||
NTDLL_from_server_abstime(&basic_info->RemainingTime, &reply->when);
|
||||
basic_info->RemainingTime.QuadPart = reply->when;
|
||||
basic_info->TimerState = reply->signaled;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
@ -670,15 +663,9 @@ static BOOL invoke_apc( const apc_call_t *call, apc_result_t *result )
|
|||
user_apc = TRUE;
|
||||
break;
|
||||
case APC_TIMER:
|
||||
{
|
||||
LARGE_INTEGER time;
|
||||
/* convert sec/usec to NT time */
|
||||
RtlSecondsSince1970ToTime( call->timer.time.sec, &time );
|
||||
time.QuadPart += call->timer.time.usec * 10;
|
||||
call->timer.func( call->timer.arg, time.u.LowPart, time.u.HighPart );
|
||||
call->timer.func( call->timer.arg, (DWORD)call->timer.time, (DWORD)(call->timer.time >> 32) );
|
||||
user_apc = TRUE;
|
||||
break;
|
||||
}
|
||||
case APC_ASYNC_IO:
|
||||
result->type = call->type;
|
||||
result->async_io.status = call->async_io.func( call->async_io.user,
|
||||
|
@ -895,10 +882,8 @@ NTSTATUS NTDLL_wait_for_multiple_objects( UINT count, const HANDLE *handles, UIN
|
|||
{
|
||||
NTSTATUS ret;
|
||||
int cookie;
|
||||
abs_time_t abs_timeout;
|
||||
timeout_t abs_timeout = timeout ? timeout->QuadPart : TIMEOUT_INFINITE;
|
||||
|
||||
NTDLL_get_server_abstime( &abs_timeout, timeout );
|
||||
if (timeout) flags |= SELECT_TIMEOUT;
|
||||
for (;;)
|
||||
{
|
||||
SERVER_START_REQ( select )
|
||||
|
@ -909,6 +894,7 @@ NTSTATUS NTDLL_wait_for_multiple_objects( UINT count, const HANDLE *handles, UIN
|
|||
req->timeout = abs_timeout;
|
||||
wine_server_add_data( req, handles, count * sizeof(HANDLE) );
|
||||
ret = wine_server_call( req );
|
||||
abs_timeout = reply->timeout;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
if (ret == STATUS_PENDING) ret = wait_reply( &cookie );
|
||||
|
@ -995,32 +981,33 @@ NTSTATUS WINAPI NtDelayExecution( BOOLEAN alertable, const LARGE_INTEGER *timeou
|
|||
return NTDLL_wait_for_multiple_objects( 0, NULL, flags, timeout, 0 );
|
||||
}
|
||||
|
||||
if (!timeout) /* sleep forever */
|
||||
if (!timeout || timeout->QuadPart == TIMEOUT_INFINITE) /* sleep forever */
|
||||
{
|
||||
for (;;) select( 0, NULL, NULL, NULL, NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
abs_time_t when;
|
||||
LARGE_INTEGER now;
|
||||
timeout_t when, diff;
|
||||
|
||||
NTDLL_get_server_abstime( &when, timeout );
|
||||
if ((when = timeout->QuadPart) < 0)
|
||||
{
|
||||
NtQuerySystemTime( &now );
|
||||
when = now.QuadPart - when;
|
||||
}
|
||||
|
||||
/* Note that we yield after establishing the desired timeout */
|
||||
NtYieldExecution();
|
||||
if (!when) return STATUS_SUCCESS;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday( &tv, 0 );
|
||||
tv.tv_sec = when.sec - tv.tv_sec;
|
||||
if ((tv.tv_usec = when.usec - tv.tv_usec) < 0)
|
||||
{
|
||||
tv.tv_usec += 1000000;
|
||||
tv.tv_sec--;
|
||||
}
|
||||
/* if our yield already passed enough time, we're done */
|
||||
if (tv.tv_sec < 0) break;
|
||||
|
||||
NtQuerySystemTime( &now );
|
||||
diff = (when - now.QuadPart + 9) / 10;
|
||||
if (diff <= 0) break;
|
||||
tv.tv_sec = diff / 1000000;
|
||||
tv.tv_usec = diff % 1000000;
|
||||
if (select( 0, NULL, NULL, NULL, &tv ) != -1) break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1186,8 +1186,8 @@ NTSTATUS WINAPI NtQueryInformationThread( HANDLE handle, THREADINFOCLASS class,
|
|||
status = wine_server_call( req );
|
||||
if (status == STATUS_SUCCESS)
|
||||
{
|
||||
NTDLL_from_server_abstime( &kusrt.CreateTime, &reply->creation_time );
|
||||
NTDLL_from_server_abstime( &kusrt.ExitTime, &reply->exit_time );
|
||||
kusrt.CreateTime.QuadPart = reply->creation_time;
|
||||
kusrt.ExitTime.QuadPart = reply->exit_time;
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
|
|
@ -446,67 +446,6 @@ static inline int IsLeapYear(int Year)
|
|||
return Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NTDLL_get_server_abstime
|
||||
*
|
||||
* Convert a NTDLL time into an abs_time_t struct to send to the server.
|
||||
*/
|
||||
void NTDLL_get_server_abstime( abs_time_t *when, const LARGE_INTEGER *timeout )
|
||||
{
|
||||
UINT remainder;
|
||||
|
||||
if (!timeout) /* infinite timeout */
|
||||
{
|
||||
when->sec = when->usec = 0;
|
||||
}
|
||||
else if (timeout->QuadPart <= 0) /* relative timeout */
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
if (-timeout->QuadPart > (LONGLONG)INT_MAX * TICKSPERSEC)
|
||||
when->sec = when->usec = INT_MAX;
|
||||
else
|
||||
{
|
||||
ULONG sec = RtlEnlargedUnsignedDivide( -timeout->QuadPart, TICKSPERSEC, &remainder );
|
||||
gettimeofday( &tv, 0 );
|
||||
when->sec = tv.tv_sec + sec;
|
||||
if ((when->usec = tv.tv_usec + (remainder / 10)) >= 1000000)
|
||||
{
|
||||
when->usec -= 1000000;
|
||||
when->sec++;
|
||||
}
|
||||
if (when->sec < tv.tv_sec) /* overflow */
|
||||
when->sec = when->usec = INT_MAX;
|
||||
}
|
||||
}
|
||||
else /* absolute time */
|
||||
{
|
||||
if (timeout->QuadPart < TICKS_1601_TO_1970)
|
||||
when->sec = when->usec = 0;
|
||||
else if (timeout->QuadPart > TICKS_1601_TO_UNIX_MAX)
|
||||
when->sec = when->usec = INT_MAX;
|
||||
else
|
||||
{
|
||||
when->sec = RtlEnlargedUnsignedDivide( timeout->QuadPart - TICKS_1601_TO_1970,
|
||||
TICKSPERSEC, &remainder );
|
||||
when->usec = remainder / 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* NTDLL_from_server_abstime
|
||||
*
|
||||
* Convert a timeval struct from the server into an NTDLL time.
|
||||
*/
|
||||
void NTDLL_from_server_abstime( LARGE_INTEGER *time, const abs_time_t *when )
|
||||
{
|
||||
time->QuadPart = when->sec * (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1970;
|
||||
time->QuadPart += when->usec * 10;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* RtlTimeToTimeFields [NTDLL.@]
|
||||
*
|
||||
|
@ -878,16 +817,15 @@ NTSTATUS WINAPI NtQuerySystemTime( PLARGE_INTEGER Time )
|
|||
*/
|
||||
NTSTATUS WINAPI NtQueryPerformanceCounter( PLARGE_INTEGER Counter, PLARGE_INTEGER Frequency )
|
||||
{
|
||||
struct timeval now;
|
||||
LARGE_INTEGER now;
|
||||
|
||||
if (!Counter) return STATUS_ACCESS_VIOLATION;
|
||||
gettimeofday( &now, 0 );
|
||||
/* convert a counter that increments at a rate of 1 MHz
|
||||
|
||||
/* convert a counter that increments at a rate of 10 MHz
|
||||
* to one of 1.193182 MHz, with some care for arithmetic
|
||||
* overflow ( will not overflow for 5000 years ) and
|
||||
* good accuracy ( 105/88 = 1.19318182) */
|
||||
Counter->QuadPart = (((now.tv_sec - server_start_time.sec) * (ULONGLONG)1000000 +
|
||||
(now.tv_usec - server_start_time.usec)) * 105) / 88;
|
||||
* overflow and good accuracy (21/176 = 0.11931818) */
|
||||
NtQuerySystemTime( &now );
|
||||
Counter->QuadPart = ((now.QuadPart - server_start_time) * 21) / 176;
|
||||
if (Frequency) Frequency->QuadPart = 1193182;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -899,11 +837,10 @@ NTSTATUS WINAPI NtQueryPerformanceCounter( PLARGE_INTEGER Counter, PLARGE_INTEGE
|
|||
*/
|
||||
ULONG WINAPI NtGetTickCount(void)
|
||||
{
|
||||
struct timeval current_time;
|
||||
LARGE_INTEGER now;
|
||||
|
||||
gettimeofday(¤t_time, NULL);
|
||||
return (current_time.tv_sec - server_start_time.sec) * 1000 +
|
||||
(current_time.tv_usec - server_start_time.usec) / 1000;
|
||||
NtQuerySystemTime( &now );
|
||||
return (now.QuadPart - server_start_time) / 10000;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1399,7 +1399,7 @@ static BOOL post_dde_message( struct packed_message *data, const struct send_mes
|
|||
req->msg = info->msg;
|
||||
req->wparam = info->wparam;
|
||||
req->lparam = lp;
|
||||
req->timeout = 0;
|
||||
req->timeout = TIMEOUT_INFINITE;
|
||||
for (i = 0; i < data->count; i++)
|
||||
wine_server_add_data( req, data->data[i], data->size[i] );
|
||||
if ((res = wine_server_call( req )))
|
||||
|
@ -2201,7 +2201,8 @@ static BOOL put_message_in_queue( const struct send_message_info *info, size_t *
|
|||
struct packed_message data;
|
||||
message_data_t msg_data;
|
||||
unsigned int res;
|
||||
int i, timeout = 0;
|
||||
int i;
|
||||
timeout_t timeout = TIMEOUT_INFINITE;
|
||||
|
||||
/* Check for INFINITE timeout for compatibility with Win9x,
|
||||
* although Windows >= NT does not do so
|
||||
|
@ -2209,8 +2210,12 @@ static BOOL put_message_in_queue( const struct send_message_info *info, size_t *
|
|||
if (info->type != MSG_NOTIFY &&
|
||||
info->type != MSG_CALLBACK &&
|
||||
info->type != MSG_POSTED &&
|
||||
info->timeout &&
|
||||
info->timeout != INFINITE)
|
||||
timeout = info->timeout;
|
||||
{
|
||||
/* timeout is signed despite the prototype */
|
||||
timeout = (timeout_t)max( 0, (int)info->timeout ) * -10000;
|
||||
}
|
||||
|
||||
data.count = 0;
|
||||
if (info->type == MSG_OTHER_PROCESS)
|
||||
|
|
|
@ -133,11 +133,8 @@ struct wake_up_reply
|
|||
};
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int sec;
|
||||
int usec;
|
||||
} abs_time_t;
|
||||
typedef __int64 timeout_t;
|
||||
#define TIMEOUT_INFINITE (((timeout_t)0x7fffffff) << 32 | 0xffffffff)
|
||||
|
||||
|
||||
typedef struct
|
||||
|
@ -257,7 +254,7 @@ typedef union
|
|||
{
|
||||
enum apc_type type;
|
||||
void (__stdcall *func)(void*, unsigned int, unsigned int);
|
||||
abs_time_t time;
|
||||
timeout_t time;
|
||||
void *arg;
|
||||
} timer;
|
||||
struct
|
||||
|
@ -540,7 +537,7 @@ struct init_thread_reply
|
|||
process_id_t pid;
|
||||
thread_id_t tid;
|
||||
data_size_t info_size;
|
||||
abs_time_t server_start;
|
||||
timeout_t server_start;
|
||||
int version;
|
||||
};
|
||||
|
||||
|
@ -589,8 +586,8 @@ struct get_process_info_reply
|
|||
int priority;
|
||||
int affinity;
|
||||
void* peb;
|
||||
abs_time_t start_time;
|
||||
abs_time_t end_time;
|
||||
timeout_t start_time;
|
||||
timeout_t end_time;
|
||||
};
|
||||
|
||||
|
||||
|
@ -627,8 +624,8 @@ struct get_thread_info_reply
|
|||
int exit_code;
|
||||
int priority;
|
||||
int affinity;
|
||||
abs_time_t creation_time;
|
||||
abs_time_t exit_time;
|
||||
timeout_t creation_time;
|
||||
timeout_t exit_time;
|
||||
int last;
|
||||
};
|
||||
|
||||
|
@ -856,17 +853,17 @@ struct select_request
|
|||
int flags;
|
||||
void* cookie;
|
||||
obj_handle_t signal;
|
||||
abs_time_t timeout;
|
||||
timeout_t timeout;
|
||||
/* VARARG(handles,handles); */
|
||||
};
|
||||
struct select_reply
|
||||
{
|
||||
struct reply_header __header;
|
||||
timeout_t timeout;
|
||||
};
|
||||
#define SELECT_ALL 1
|
||||
#define SELECT_ALERTABLE 2
|
||||
#define SELECT_INTERRUPTIBLE 4
|
||||
#define SELECT_TIMEOUT 8
|
||||
|
||||
|
||||
|
||||
|
@ -2181,7 +2178,7 @@ struct set_timer_request
|
|||
{
|
||||
struct request_header __header;
|
||||
obj_handle_t handle;
|
||||
abs_time_t expire;
|
||||
timeout_t expire;
|
||||
int period;
|
||||
void* callback;
|
||||
void* arg;
|
||||
|
@ -2213,7 +2210,7 @@ struct get_timer_info_request
|
|||
struct get_timer_info_reply
|
||||
{
|
||||
struct reply_header __header;
|
||||
abs_time_t when;
|
||||
timeout_t when;
|
||||
int signaled;
|
||||
};
|
||||
|
||||
|
@ -2442,7 +2439,7 @@ struct send_message_request
|
|||
unsigned int msg;
|
||||
unsigned long wparam;
|
||||
unsigned long lparam;
|
||||
int timeout;
|
||||
timeout_t timeout;
|
||||
/* VARARG(data,message_data); */
|
||||
};
|
||||
struct send_message_reply
|
||||
|
@ -2694,7 +2691,7 @@ struct create_named_pipe_request
|
|||
unsigned int maxinstances;
|
||||
unsigned int outsize;
|
||||
unsigned int insize;
|
||||
unsigned int timeout;
|
||||
timeout_t timeout;
|
||||
/* VARARG(name,unicode_str); */
|
||||
};
|
||||
struct create_named_pipe_reply
|
||||
|
@ -2728,7 +2725,7 @@ struct wait_named_pipe_request
|
|||
struct request_header __header;
|
||||
obj_handle_t handle;
|
||||
async_data_t async;
|
||||
unsigned int timeout;
|
||||
timeout_t timeout;
|
||||
/* VARARG(name,unicode_str); */
|
||||
};
|
||||
struct wait_named_pipe_reply
|
||||
|
@ -3853,7 +3850,7 @@ struct create_mailslot_request
|
|||
unsigned int attributes;
|
||||
obj_handle_t rootdir;
|
||||
unsigned int max_msgsize;
|
||||
int read_timeout;
|
||||
timeout_t read_timeout;
|
||||
/* VARARG(name,unicode_str); */
|
||||
};
|
||||
struct create_mailslot_reply
|
||||
|
@ -3869,13 +3866,13 @@ struct set_mailslot_info_request
|
|||
struct request_header __header;
|
||||
obj_handle_t handle;
|
||||
unsigned int flags;
|
||||
int read_timeout;
|
||||
timeout_t read_timeout;
|
||||
};
|
||||
struct set_mailslot_info_reply
|
||||
{
|
||||
struct reply_header __header;
|
||||
unsigned int max_msgsize;
|
||||
int read_timeout;
|
||||
timeout_t read_timeout;
|
||||
};
|
||||
#define MAILSLOT_SET_READ_TIMEOUT 1
|
||||
|
||||
|
@ -4660,6 +4657,6 @@ union generic_reply
|
|||
struct allocate_locally_unique_id_reply allocate_locally_unique_id_reply;
|
||||
};
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 295
|
||||
#define SERVER_PROTOCOL_VERSION 296
|
||||
|
||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||
|
|
|
@ -214,10 +214,10 @@ struct async *create_async( struct thread *thread, struct async_queue *queue, co
|
|||
}
|
||||
|
||||
/* set the timeout of an async operation */
|
||||
void async_set_timeout( struct async *async, const struct timeval *timeout, unsigned int status )
|
||||
void async_set_timeout( struct async *async, timeout_t timeout, unsigned int status )
|
||||
{
|
||||
if (async->timeout) remove_timeout_user( async->timeout );
|
||||
if (timeout) async->timeout = add_timeout_user( timeout, async_timeout, async );
|
||||
if (timeout != TIMEOUT_INFINITE) async->timeout = add_timeout_user( timeout, async_timeout, async );
|
||||
else async->timeout = NULL;
|
||||
async->timeout_status = status;
|
||||
}
|
||||
|
|
73
server/fd.c
73
server/fd.c
|
@ -322,23 +322,30 @@ static file_pos_t max_unix_offset = OFF_T_MAX;
|
|||
struct timeout_user
|
||||
{
|
||||
struct list entry; /* entry in sorted timeout list */
|
||||
struct timeval when; /* timeout expiry (absolute time) */
|
||||
timeout_t when; /* timeout expiry (absolute time) */
|
||||
timeout_callback callback; /* callback function */
|
||||
void *private; /* callback private data */
|
||||
};
|
||||
|
||||
static struct list timeout_list = LIST_INIT(timeout_list); /* sorted timeouts list */
|
||||
struct timeval current_time;
|
||||
timeout_t current_time;
|
||||
|
||||
static inline void set_current_time(void)
|
||||
{
|
||||
static const timeout_t ticks_1601_to_1970 = (timeout_t)86400 * (369 * 365 + 89) * TICKS_PER_SEC;
|
||||
struct timeval now;
|
||||
gettimeofday( &now, NULL );
|
||||
current_time = (timeout_t)now.tv_sec * TICKS_PER_SEC + now.tv_usec * 10 + ticks_1601_to_1970;
|
||||
}
|
||||
|
||||
/* add a timeout user */
|
||||
struct timeout_user *add_timeout_user( const struct timeval *when, timeout_callback func,
|
||||
void *private )
|
||||
struct timeout_user *add_timeout_user( timeout_t when, timeout_callback func, void *private )
|
||||
{
|
||||
struct timeout_user *user;
|
||||
struct list *ptr;
|
||||
|
||||
if (!(user = mem_alloc( sizeof(*user) ))) return NULL;
|
||||
user->when = *when;
|
||||
user->when = (when > 0) ? when : current_time - when;
|
||||
user->callback = func;
|
||||
user->private = private;
|
||||
|
||||
|
@ -347,7 +354,7 @@ struct timeout_user *add_timeout_user( const struct timeval *when, timeout_callb
|
|||
LIST_FOR_EACH( ptr, &timeout_list )
|
||||
{
|
||||
struct timeout_user *timeout = LIST_ENTRY( ptr, struct timeout_user, entry );
|
||||
if (!time_before( &timeout->when, when )) break;
|
||||
if (timeout->when >= user->when) break;
|
||||
}
|
||||
list_add_before( ptr, &user->entry );
|
||||
return user;
|
||||
|
@ -360,19 +367,39 @@ void remove_timeout_user( struct timeout_user *user )
|
|||
free( user );
|
||||
}
|
||||
|
||||
/* add a timeout in milliseconds to an absolute time */
|
||||
void add_timeout( struct timeval *when, int timeout )
|
||||
/* return a text description of a timeout for debugging purposes */
|
||||
const char *get_timeout_str( timeout_t timeout )
|
||||
{
|
||||
if (timeout)
|
||||
static char buffer[64];
|
||||
long secs, nsecs;
|
||||
|
||||
if (!timeout) return "0";
|
||||
if (timeout == TIMEOUT_INFINITE) return "infinite";
|
||||
|
||||
if (timeout < 0) /* relative */
|
||||
{
|
||||
long sec = timeout / 1000;
|
||||
if ((when->tv_usec += (timeout - 1000*sec) * 1000) >= 1000000)
|
||||
{
|
||||
when->tv_usec -= 1000000;
|
||||
when->tv_sec++;
|
||||
}
|
||||
when->tv_sec += sec;
|
||||
secs = -timeout / TICKS_PER_SEC;
|
||||
nsecs = -timeout % TICKS_PER_SEC;
|
||||
sprintf( buffer, "+%ld.%07ld", secs, nsecs );
|
||||
}
|
||||
else /* absolute */
|
||||
{
|
||||
secs = (timeout - current_time) / TICKS_PER_SEC;
|
||||
nsecs = (timeout - current_time) % TICKS_PER_SEC;
|
||||
if (nsecs < 0)
|
||||
{
|
||||
nsecs += TICKS_PER_SEC;
|
||||
secs--;
|
||||
}
|
||||
if (secs >= 0)
|
||||
sprintf( buffer, "%x%08x (+%ld.%07ld)",
|
||||
(unsigned int)(timeout >> 32), (unsigned int)timeout, secs, nsecs );
|
||||
else
|
||||
sprintf( buffer, "%x%08x (-%ld.%07ld)",
|
||||
(unsigned int)(timeout >> 32), (unsigned int)timeout,
|
||||
-(secs + 1), TICKS_PER_SEC - nsecs );
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
|
@ -467,7 +494,7 @@ static inline void main_loop_epoll(void)
|
|||
if (epoll_fd == -1) break; /* an error occurred with epoll */
|
||||
|
||||
ret = epoll_wait( epoll_fd, events, sizeof(events)/sizeof(events[0]), timeout );
|
||||
gettimeofday( ¤t_time, NULL );
|
||||
set_current_time();
|
||||
|
||||
/* put the events into the pollfd array first, like poll does */
|
||||
for (i = 0; i < ret; i++)
|
||||
|
@ -573,7 +600,7 @@ static inline void main_loop_epoll(void)
|
|||
}
|
||||
else ret = kevent( kqueue_fd, NULL, 0, events, sizeof(events)/sizeof(events[0]), NULL );
|
||||
|
||||
gettimeofday( ¤t_time, NULL );
|
||||
set_current_time();
|
||||
|
||||
/* put the events into the pollfd array first, like poll does */
|
||||
for (i = 0; i < ret; i++)
|
||||
|
@ -679,7 +706,7 @@ static int get_next_timeout(void)
|
|||
{
|
||||
struct timeout_user *timeout = LIST_ENTRY( ptr, struct timeout_user, entry );
|
||||
|
||||
if (!time_before( ¤t_time, &timeout->when ))
|
||||
if (timeout->when <= current_time)
|
||||
{
|
||||
list_remove( &timeout->entry );
|
||||
list_add_tail( &expired_list, &timeout->entry );
|
||||
|
@ -700,8 +727,7 @@ static int get_next_timeout(void)
|
|||
if ((ptr = list_head( &timeout_list )) != NULL)
|
||||
{
|
||||
struct timeout_user *timeout = LIST_ENTRY( ptr, struct timeout_user, entry );
|
||||
int diff = (timeout->when.tv_sec - current_time.tv_sec) * 1000
|
||||
+ (timeout->when.tv_usec - current_time.tv_usec + 999) / 1000;
|
||||
int diff = (timeout->when - current_time + 9999) / 10000;
|
||||
if (diff < 0) diff = 0;
|
||||
return diff;
|
||||
}
|
||||
|
@ -714,7 +740,8 @@ void main_loop(void)
|
|||
{
|
||||
int i, ret, timeout;
|
||||
|
||||
gettimeofday( ¤t_time, NULL );
|
||||
set_current_time();
|
||||
server_start_time = current_time;
|
||||
|
||||
main_loop_epoll();
|
||||
/* fall through to normal poll loop */
|
||||
|
@ -726,7 +753,7 @@ void main_loop(void)
|
|||
if (!active_users) break; /* last user removed by a timeout */
|
||||
|
||||
ret = poll( pollfd, nb_users, timeout );
|
||||
gettimeofday( ¤t_time, NULL );
|
||||
set_current_time();
|
||||
|
||||
if (ret > 0)
|
||||
{
|
||||
|
|
|
@ -91,20 +91,15 @@ static inline struct fd *get_obj_fd( struct object *obj ) { return obj->ops->get
|
|||
/* timeout functions */
|
||||
|
||||
struct timeout_user;
|
||||
extern struct timeval current_time;
|
||||
extern timeout_t current_time;
|
||||
|
||||
#define TICKS_PER_SEC 10000000
|
||||
|
||||
typedef void (*timeout_callback)( void *private );
|
||||
|
||||
extern struct timeout_user *add_timeout_user( const struct timeval *when,
|
||||
timeout_callback func, void *private );
|
||||
extern struct timeout_user *add_timeout_user( timeout_t when, timeout_callback func, void *private );
|
||||
extern void remove_timeout_user( struct timeout_user *user );
|
||||
extern void add_timeout( struct timeval *when, int timeout );
|
||||
/* return 1 if t1 is before t2 */
|
||||
static inline int time_before( const struct timeval *t1, const struct timeval *t2 )
|
||||
{
|
||||
return ((t1->tv_sec < t2->tv_sec) ||
|
||||
((t1->tv_sec == t2->tv_sec) && (t1->tv_usec < t2->tv_usec)));
|
||||
}
|
||||
extern const char *get_timeout_str( timeout_t timeout );
|
||||
|
||||
/* file functions */
|
||||
|
||||
|
@ -133,8 +128,7 @@ extern struct async_queue *create_async_queue( struct fd *fd );
|
|||
extern void free_async_queue( struct async_queue *queue );
|
||||
extern struct async *create_async( struct thread *thread, struct async_queue *queue,
|
||||
const async_data_t *data );
|
||||
extern void async_set_timeout( struct async *async, const struct timeval *timeout,
|
||||
unsigned int status );
|
||||
extern void async_set_timeout( struct async *async, timeout_t timeout, unsigned int status );
|
||||
extern void async_set_result( struct object *obj, unsigned int status );
|
||||
extern int async_waiting( struct async_queue *queue );
|
||||
extern void async_wake_up( struct async_queue *queue, unsigned int status );
|
||||
|
|
|
@ -58,7 +58,7 @@ struct mailslot
|
|||
struct fd *fd;
|
||||
int write_fd;
|
||||
unsigned int max_msgsize;
|
||||
int read_timeout;
|
||||
timeout_t read_timeout;
|
||||
struct list writers;
|
||||
};
|
||||
|
||||
|
@ -214,8 +214,8 @@ static void mailslot_dump( struct object *obj, int verbose )
|
|||
struct mailslot *mailslot = (struct mailslot *) obj;
|
||||
|
||||
assert( obj->ops == &mailslot_ops );
|
||||
fprintf( stderr, "Mailslot max_msgsize=%d read_timeout=%d\n",
|
||||
mailslot->max_msgsize, mailslot->read_timeout );
|
||||
fprintf( stderr, "Mailslot max_msgsize=%d read_timeout=%s\n",
|
||||
mailslot->max_msgsize, get_timeout_str(mailslot->read_timeout) );
|
||||
}
|
||||
|
||||
static enum server_fd_type mailslot_get_fd_type( struct fd *fd )
|
||||
|
@ -299,12 +299,8 @@ static void mailslot_queue_async( struct fd *fd, const async_data_t *data, int t
|
|||
|
||||
if ((async = fd_queue_async( fd, data, type, count )))
|
||||
{
|
||||
if (mailslot->read_timeout != -1)
|
||||
{
|
||||
struct timeval when = current_time;
|
||||
add_timeout( &when, max(1,mailslot->read_timeout) );
|
||||
async_set_timeout( async, &when, STATUS_IO_TIMEOUT );
|
||||
}
|
||||
async_set_timeout( async, mailslot->read_timeout ? mailslot->read_timeout : -1,
|
||||
STATUS_IO_TIMEOUT );
|
||||
release_object( async );
|
||||
set_error( STATUS_PENDING );
|
||||
}
|
||||
|
@ -375,7 +371,7 @@ void create_mailslot_device( struct directory *root, const struct unicode_str *n
|
|||
|
||||
static struct mailslot *create_mailslot( struct directory *root,
|
||||
const struct unicode_str *name, unsigned int attr,
|
||||
int max_msgsize, int read_timeout )
|
||||
int max_msgsize, timeout_t read_timeout )
|
||||
{
|
||||
struct object *obj;
|
||||
struct unicode_str new_name;
|
||||
|
|
|
@ -36,8 +36,8 @@
|
|||
|
||||
/* command-line options */
|
||||
int debug_level = 0;
|
||||
int master_socket_timeout = 3; /* master socket timeout in seconds, default is 3 s */
|
||||
int foreground = 0;
|
||||
timeout_t master_socket_timeout = 3 * -TICKS_PER_SEC; /* master socket timeout, default is 3 seconds */
|
||||
const char *server_argv0;
|
||||
|
||||
/* parse-line args */
|
||||
|
@ -84,8 +84,10 @@ static void parse_args( int argc, char *argv[] )
|
|||
else ret = kill_lock_owner(-1);
|
||||
exit( !ret );
|
||||
case 'p':
|
||||
if (isdigit(argv[i][2])) master_socket_timeout = atoi( argv[i] + 2 );
|
||||
else master_socket_timeout = -1;
|
||||
if (isdigit(argv[i][2]))
|
||||
master_socket_timeout = (timeout_t)atoi( argv[i] + 2 ) * -TICKS_PER_SEC;
|
||||
else
|
||||
master_socket_timeout = TIMEOUT_INFINITE;
|
||||
break;
|
||||
case 'v':
|
||||
fprintf( stderr, "%s\n", PACKAGE_STRING );
|
||||
|
|
|
@ -94,8 +94,8 @@ struct named_pipe
|
|||
unsigned int maxinstances;
|
||||
unsigned int outsize;
|
||||
unsigned int insize;
|
||||
unsigned int timeout;
|
||||
unsigned int instances;
|
||||
timeout_t timeout;
|
||||
struct list servers; /* list of servers using this pipe */
|
||||
struct async_queue *waiters; /* list of clients waiting to connect */
|
||||
};
|
||||
|
@ -512,9 +512,7 @@ static void check_flushed( void *arg )
|
|||
assert( server->event );
|
||||
if (pipe_data_remaining( server ))
|
||||
{
|
||||
struct timeval tv = current_time;
|
||||
add_timeout( &tv, 100 );
|
||||
server->flush_poll = add_timeout_user( &tv, check_flushed, server );
|
||||
server->flush_poll = add_timeout_user( -TICKS_PER_SEC / 10, check_flushed, server );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -538,14 +536,11 @@ static void pipe_server_flush( struct fd *fd, struct event **event )
|
|||
|
||||
if (pipe_data_remaining( server ))
|
||||
{
|
||||
struct timeval tv = current_time;
|
||||
|
||||
/* this kind of sux -
|
||||
/* this kind of sux -
|
||||
there's no unix way to be alerted when a pipe becomes empty */
|
||||
server->event = create_event( NULL, NULL, 0, 0, 0 );
|
||||
if (!server->event) return;
|
||||
add_timeout( &tv, 100 );
|
||||
server->flush_poll = add_timeout_user( &tv, check_flushed, server );
|
||||
server->flush_poll = add_timeout_user( -TICKS_PER_SEC / 10, check_flushed, server );
|
||||
*event = server->event;
|
||||
}
|
||||
}
|
||||
|
@ -901,13 +896,7 @@ DECL_HANDLER(wait_named_pipe)
|
|||
|
||||
if ((async = create_async( current, pipe->waiters, &req->async )))
|
||||
{
|
||||
if (req->timeout != NMPWAIT_WAIT_FOREVER)
|
||||
{
|
||||
struct timeval when = current_time;
|
||||
if (req->timeout == NMPWAIT_USE_DEFAULT_WAIT) add_timeout( &when, pipe->timeout );
|
||||
else add_timeout( &when, req->timeout );
|
||||
async_set_timeout( async, &when, STATUS_TIMEOUT );
|
||||
}
|
||||
async_set_timeout( async, req->timeout ? req->timeout : pipe->timeout, STATUS_TIMEOUT );
|
||||
release_object( async );
|
||||
set_error( STATUS_PENDING );
|
||||
}
|
||||
|
|
|
@ -214,11 +214,11 @@ extern void create_mailslot_device( struct directory *root, const struct unicode
|
|||
|
||||
/* command-line options */
|
||||
extern int debug_level;
|
||||
extern int master_socket_timeout;
|
||||
extern int foreground;
|
||||
extern timeout_t master_socket_timeout;
|
||||
extern const char *server_argv0;
|
||||
|
||||
/* server start time used for GetTickCount() */
|
||||
extern struct timeval server_start_time;
|
||||
extern timeout_t server_start_time;
|
||||
|
||||
#endif /* __WINE_SERVER_OBJECT_H */
|
||||
|
|
|
@ -244,13 +244,9 @@ static void start_sigkill_timer( struct process *process )
|
|||
{
|
||||
grab_object( process );
|
||||
if (process->unix_pid != -1 && process->msg_fd)
|
||||
{
|
||||
struct timeval when = current_time;
|
||||
|
||||
add_timeout( &when, 1000 );
|
||||
process->sigkill_timeout = add_timeout_user( &when, process_sigkill, process );
|
||||
}
|
||||
else process_died( process );
|
||||
process->sigkill_timeout = add_timeout_user( -TICKS_PER_SEC, process_sigkill, process );
|
||||
else
|
||||
process_died( process );
|
||||
}
|
||||
|
||||
/* create a new process and its main thread */
|
||||
|
@ -295,7 +291,7 @@ struct thread *create_process( int fd, struct thread *parent_thread, int inherit
|
|||
list_init( &process->dlls );
|
||||
|
||||
process->start_time = current_time;
|
||||
process->end_time.tv_sec = process->end_time.tv_usec = 0;
|
||||
process->end_time = 0;
|
||||
list_add_head( &process_list, &process->entry );
|
||||
|
||||
if (!(process->id = process->group_id = alloc_ptid( process )))
|
||||
|
@ -1013,10 +1009,8 @@ DECL_HANDLER(get_process_info)
|
|||
reply->priority = process->priority;
|
||||
reply->affinity = process->affinity;
|
||||
reply->peb = process->peb;
|
||||
reply->start_time.sec = process->start_time.tv_sec;
|
||||
reply->start_time.usec = process->start_time.tv_usec;
|
||||
reply->end_time.sec = process->end_time.tv_sec;
|
||||
reply->end_time.usec = process->end_time.tv_usec;
|
||||
reply->start_time = process->start_time;
|
||||
reply->end_time = process->end_time;
|
||||
release_object( process );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,8 +61,8 @@ struct process
|
|||
int unix_pid; /* Unix pid for final SIGKILL */
|
||||
int exit_code; /* process exit code */
|
||||
int running_threads; /* number of threads running in this process */
|
||||
struct timeval start_time; /* absolute time at process start */
|
||||
struct timeval end_time; /* absolute time at process end */
|
||||
timeout_t start_time; /* absolute time at process start */
|
||||
timeout_t end_time; /* absolute time at process end */
|
||||
int priority; /* priority class */
|
||||
int affinity; /* process affinity mask */
|
||||
int suspend; /* global process suspend count */
|
||||
|
|
|
@ -148,12 +148,9 @@ struct wake_up_reply
|
|||
int signaled; /* wait result */
|
||||
};
|
||||
|
||||
/* structure for absolute timeouts */
|
||||
typedef struct
|
||||
{
|
||||
int sec; /* seconds since Unix epoch */
|
||||
int usec; /* microseconds */
|
||||
} abs_time_t;
|
||||
/* NT-style timeout, in 100ns units, negative means relative timeout */
|
||||
typedef __int64 timeout_t;
|
||||
#define TIMEOUT_INFINITE (((timeout_t)0x7fffffff) << 32 | 0xffffffff)
|
||||
|
||||
/* structure returned in the list of window properties */
|
||||
typedef struct
|
||||
|
@ -273,7 +270,7 @@ typedef union
|
|||
{
|
||||
enum apc_type type; /* APC_TIMER */
|
||||
void (__stdcall *func)(void*, unsigned int, unsigned int);
|
||||
abs_time_t time; /* absolute time of expiration */
|
||||
timeout_t time; /* absolute time of expiration */
|
||||
void *arg; /* user argument */
|
||||
} timer;
|
||||
struct
|
||||
|
@ -525,7 +522,7 @@ typedef union
|
|||
process_id_t pid; /* process id of the new thread's process */
|
||||
thread_id_t tid; /* thread id of the new thread */
|
||||
data_size_t info_size; /* total size of startup info */
|
||||
abs_time_t server_start; /* server start time */
|
||||
timeout_t server_start; /* server start time */
|
||||
int version; /* protocol version */
|
||||
@END
|
||||
|
||||
|
@ -559,8 +556,8 @@ typedef union
|
|||
int priority; /* priority class */
|
||||
int affinity; /* process affinity mask */
|
||||
void* peb; /* PEB address in process address space */
|
||||
abs_time_t start_time; /* process start time */
|
||||
abs_time_t end_time; /* process end time */
|
||||
timeout_t start_time; /* process start time */
|
||||
timeout_t end_time; /* process end time */
|
||||
@END
|
||||
|
||||
|
||||
|
@ -586,8 +583,8 @@ typedef union
|
|||
int exit_code; /* thread exit code */
|
||||
int priority; /* thread priority level */
|
||||
int affinity; /* thread affinity mask */
|
||||
abs_time_t creation_time; /* thread creation time */
|
||||
abs_time_t exit_time; /* thread exit time */
|
||||
timeout_t creation_time; /* thread creation time */
|
||||
timeout_t exit_time; /* thread exit time */
|
||||
int last; /* last thread in process */
|
||||
@END
|
||||
|
||||
|
@ -739,13 +736,14 @@ typedef union
|
|||
int flags; /* wait flags (see below) */
|
||||
void* cookie; /* magic cookie to return to client */
|
||||
obj_handle_t signal; /* object to signal (0 if none) */
|
||||
abs_time_t timeout; /* absolute timeout */
|
||||
timeout_t timeout; /* timeout */
|
||||
VARARG(handles,handles); /* handles to select on */
|
||||
@REPLY
|
||||
timeout_t timeout; /* timeout converted to absolute */
|
||||
@END
|
||||
#define SELECT_ALL 1
|
||||
#define SELECT_ALERTABLE 2
|
||||
#define SELECT_INTERRUPTIBLE 4
|
||||
#define SELECT_TIMEOUT 8
|
||||
|
||||
|
||||
/* Create an event */
|
||||
|
@ -1647,7 +1645,7 @@ enum char_info_mode
|
|||
/* Set a waitable timer */
|
||||
@REQ(set_timer)
|
||||
obj_handle_t handle; /* handle to the timer */
|
||||
abs_time_t expire; /* next expiration absolute time */
|
||||
timeout_t expire; /* next expiration absolute time */
|
||||
int period; /* timer period in ms */
|
||||
void* callback; /* callback function */
|
||||
void* arg; /* callback argument */
|
||||
|
@ -1666,7 +1664,7 @@ enum char_info_mode
|
|||
@REQ(get_timer_info)
|
||||
obj_handle_t handle; /* handle to the timer */
|
||||
@REPLY
|
||||
abs_time_t when; /* absolute time when the timer next expires */
|
||||
timeout_t when; /* absolute time when the timer next expires */
|
||||
int signaled; /* is the timer signaled? */
|
||||
@END
|
||||
|
||||
|
@ -1814,7 +1812,7 @@ enum char_info_mode
|
|||
unsigned int msg; /* message code */
|
||||
unsigned long wparam; /* parameters */
|
||||
unsigned long lparam; /* parameters */
|
||||
int timeout; /* timeout for reply */
|
||||
timeout_t timeout; /* timeout for reply */
|
||||
VARARG(data,message_data); /* message data for sent messages */
|
||||
@END
|
||||
|
||||
|
@ -1987,7 +1985,7 @@ enum message_type
|
|||
unsigned int maxinstances;
|
||||
unsigned int outsize;
|
||||
unsigned int insize;
|
||||
unsigned int timeout;
|
||||
timeout_t timeout;
|
||||
VARARG(name,unicode_str); /* pipe name */
|
||||
@REPLY
|
||||
obj_handle_t handle; /* handle to the pipe */
|
||||
|
@ -2010,7 +2008,7 @@ enum message_type
|
|||
@REQ(wait_named_pipe)
|
||||
obj_handle_t handle;
|
||||
async_data_t async; /* async I/O parameters */
|
||||
unsigned int timeout;
|
||||
timeout_t timeout;
|
||||
VARARG(name,unicode_str); /* pipe name */
|
||||
@END
|
||||
|
||||
|
@ -2774,7 +2772,7 @@ enum message_type
|
|||
unsigned int attributes; /* object attributes */
|
||||
obj_handle_t rootdir; /* root directory */
|
||||
unsigned int max_msgsize;
|
||||
int read_timeout;
|
||||
timeout_t read_timeout;
|
||||
VARARG(name,unicode_str); /* mailslot name */
|
||||
@REPLY
|
||||
obj_handle_t handle; /* handle to the mailslot */
|
||||
|
@ -2785,10 +2783,10 @@ enum message_type
|
|||
@REQ(set_mailslot_info)
|
||||
obj_handle_t handle; /* handle to the mailslot */
|
||||
unsigned int flags;
|
||||
int read_timeout;
|
||||
timeout_t read_timeout;
|
||||
@REPLY
|
||||
unsigned int max_msgsize;
|
||||
int read_timeout;
|
||||
timeout_t read_timeout;
|
||||
@END
|
||||
#define MAILSLOT_SET_READ_TIMEOUT 1
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ struct message
|
|||
struct timer
|
||||
{
|
||||
struct list entry; /* entry in timer list */
|
||||
struct timeval when; /* next expiration */
|
||||
timeout_t when; /* next expiration */
|
||||
unsigned int rate; /* timer rate in ms */
|
||||
user_handle_t win; /* window handle */
|
||||
unsigned int msg; /* message to post */
|
||||
|
@ -131,7 +131,7 @@ struct msg_queue
|
|||
struct timeout_user *timeout; /* timeout for next timer to expire */
|
||||
struct thread_input *input; /* thread input descriptor */
|
||||
struct hook_table *hooks; /* hook table */
|
||||
struct timeval last_get_msg; /* time of last get message call */
|
||||
timeout_t last_get_msg; /* time of last get message call */
|
||||
};
|
||||
|
||||
static void msg_queue_dump( struct object *obj, int verbose );
|
||||
|
@ -536,7 +536,7 @@ static void result_timeout( void *private )
|
|||
/* allocate and fill a message result structure */
|
||||
static struct message_result *alloc_message_result( struct msg_queue *send_queue,
|
||||
struct msg_queue *recv_queue,
|
||||
struct message *msg, int timeout )
|
||||
struct message *msg, timeout_t timeout )
|
||||
{
|
||||
struct message_result *result = mem_alloc( sizeof(*result) );
|
||||
if (result)
|
||||
|
@ -583,12 +583,8 @@ static struct message_result *alloc_message_result( struct msg_queue *send_queue
|
|||
list_add_head( &send_queue->send_result, &result->sender_entry );
|
||||
}
|
||||
|
||||
if (timeout)
|
||||
{
|
||||
struct timeval when = current_time;
|
||||
add_timeout( &when, timeout );
|
||||
result->timeout = add_timeout_user( &when, result_timeout, result );
|
||||
}
|
||||
if (timeout != TIMEOUT_INFINITE)
|
||||
result->timeout = add_timeout_user( timeout, result_timeout, result );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -766,7 +762,7 @@ static int is_queue_hung( struct msg_queue *queue )
|
|||
{
|
||||
struct wait_queue_entry *entry;
|
||||
|
||||
if (current_time.tv_sec - queue->last_get_msg.tv_sec <= 5)
|
||||
if (current_time - queue->last_get_msg <= 5 * TICKS_PER_SEC)
|
||||
return 0; /* less than 5 seconds since last get message -> not hung */
|
||||
|
||||
LIST_FOR_EACH_ENTRY( entry, &queue->obj.wait_queue, struct wait_queue_entry, entry )
|
||||
|
@ -997,7 +993,7 @@ static void set_next_timer( struct msg_queue *queue )
|
|||
if ((ptr = list_head( &queue->pending_timers )))
|
||||
{
|
||||
struct timer *timer = LIST_ENTRY( ptr, struct timer, entry );
|
||||
queue->timeout = add_timeout_user( &timer->when, timer_callback, queue );
|
||||
queue->timeout = add_timeout_user( timer->when, timer_callback, queue );
|
||||
}
|
||||
/* set/clear QS_TIMER bit */
|
||||
if (list_empty( &queue->expired_timers ))
|
||||
|
@ -1049,7 +1045,7 @@ static void link_timer( struct msg_queue *queue, struct timer *timer )
|
|||
for (ptr = queue->pending_timers.next; ptr != &queue->pending_timers; ptr = ptr->next)
|
||||
{
|
||||
struct timer *t = LIST_ENTRY( ptr, struct timer, entry );
|
||||
if (!time_before( &t->when, &timer->when )) break;
|
||||
if (t->when >= timer->when) break;
|
||||
}
|
||||
list_add_before( ptr, &timer->entry );
|
||||
}
|
||||
|
@ -1066,7 +1062,7 @@ static void free_timer( struct msg_queue *queue, struct timer *timer )
|
|||
static void restart_timer( struct msg_queue *queue, struct timer *timer )
|
||||
{
|
||||
list_remove( &timer->entry );
|
||||
while (!time_before( ¤t_time, &timer->when )) add_timeout( &timer->when, timer->rate );
|
||||
while (timer->when <= current_time) timer->when += (timeout_t)timer->rate * 10000;
|
||||
link_timer( queue, timer );
|
||||
set_next_timer( queue );
|
||||
}
|
||||
|
@ -1098,8 +1094,7 @@ static struct timer *set_timer( struct msg_queue *queue, unsigned int rate )
|
|||
if (timer)
|
||||
{
|
||||
timer->rate = max( rate, 1 );
|
||||
timer->when = current_time;
|
||||
add_timeout( &timer->when, rate );
|
||||
timer->when = current_time + (timeout_t)timer->rate * 10000;
|
||||
link_timer( queue, timer );
|
||||
/* check if we replaced the next timer */
|
||||
if (list_head( &queue->pending_timers ) == &timer->entry) set_next_timer( queue );
|
||||
|
|
|
@ -103,7 +103,7 @@ struct key_value
|
|||
/* the root of the registry tree */
|
||||
static struct key *root_key;
|
||||
|
||||
static const int save_period = 30000; /* delay between periodic saves (in ms) */
|
||||
static const timeout_t save_period = 30 * -TICKS_PER_SEC; /* delay between periodic saves */
|
||||
static struct timeout_user *save_timeout_user; /* saving timer */
|
||||
|
||||
static void set_periodic_save_timer(void);
|
||||
|
@ -1683,11 +1683,8 @@ static void periodic_save( void *arg )
|
|||
/* start the periodic save timer */
|
||||
static void set_periodic_save_timer(void)
|
||||
{
|
||||
struct timeval next = current_time;
|
||||
|
||||
add_timeout( &next, save_period );
|
||||
if (save_timeout_user) remove_timeout_user( save_timeout_user );
|
||||
save_timeout_user = add_timeout_user( &next, periodic_save, NULL );
|
||||
save_timeout_user = add_timeout_user( save_period, periodic_save, NULL );
|
||||
}
|
||||
|
||||
/* save the modified registry branches to disk */
|
||||
|
|
|
@ -117,7 +117,7 @@ static const struct fd_ops master_socket_fd_ops =
|
|||
|
||||
struct thread *current = NULL; /* thread handling the current request */
|
||||
unsigned int global_error = 0; /* global error code for when no thread is current */
|
||||
struct timeval server_start_time = { 0, 0 }; /* server startup time */
|
||||
timeout_t server_start_time = 0; /* server startup time */
|
||||
|
||||
static struct master_socket *master_socket; /* the master socket object */
|
||||
static int force_shutdown;
|
||||
|
@ -468,8 +468,7 @@ int send_client_fd( struct process *process, int fd, obj_handle_t handle )
|
|||
/* get current tick count to return to client */
|
||||
unsigned int get_tick_count(void)
|
||||
{
|
||||
return ((current_time.tv_sec - server_start_time.tv_sec) * 1000) +
|
||||
((current_time.tv_usec - server_start_time.tv_usec) / 1000);
|
||||
return (current_time - server_start_time) / 10000;
|
||||
}
|
||||
|
||||
static void master_socket_dump( struct object *obj, int verbose )
|
||||
|
@ -801,9 +800,6 @@ void open_master_socket(void)
|
|||
msghdr.msg_iov = &myiovec;
|
||||
msghdr.msg_iovlen = 1;
|
||||
|
||||
/* init startup time */
|
||||
gettimeofday( &server_start_time, NULL );
|
||||
|
||||
/* init the process tracing mechanism */
|
||||
init_tracing_mechanism();
|
||||
}
|
||||
|
@ -828,15 +824,12 @@ static void close_socket_timeout( void *arg )
|
|||
/* close the master socket and stop waiting for new clients */
|
||||
void close_master_socket(void)
|
||||
{
|
||||
if (master_socket_timeout == -1) return; /* just keep running forever */
|
||||
if (master_socket_timeout == TIMEOUT_INFINITE) return; /* just keep running forever */
|
||||
|
||||
if (master_socket_timeout)
|
||||
{
|
||||
struct timeval when = current_time;
|
||||
add_timeout( &when, master_socket_timeout * 1000 );
|
||||
master_socket->timeout = add_timeout_user( &when, close_socket_timeout, NULL );
|
||||
}
|
||||
else close_socket_timeout( NULL ); /* close it right away */
|
||||
master_socket->timeout = add_timeout_user( master_socket_timeout, close_socket_timeout, NULL );
|
||||
else
|
||||
close_socket_timeout( NULL ); /* close it right away */
|
||||
}
|
||||
|
||||
/* forced shutdown, used for wineserver -k */
|
||||
|
|
|
@ -180,7 +180,7 @@ static enum server_fd_type serial_get_fd_type( struct fd *fd )
|
|||
static void serial_queue_async( struct fd *fd, const async_data_t *data, int type, int count )
|
||||
{
|
||||
struct serial *serial = get_fd_user( fd );
|
||||
int timeout = 0;
|
||||
timeout_t timeout = 0;
|
||||
struct async *async;
|
||||
|
||||
assert(serial->obj.ops == &serial_ops);
|
||||
|
@ -188,21 +188,16 @@ static void serial_queue_async( struct fd *fd, const async_data_t *data, int typ
|
|||
switch (type)
|
||||
{
|
||||
case ASYNC_TYPE_READ:
|
||||
timeout = serial->readconst + serial->readmult*count;
|
||||
timeout = serial->readconst + (timeout_t)serial->readmult*count;
|
||||
break;
|
||||
case ASYNC_TYPE_WRITE:
|
||||
timeout = serial->writeconst + serial->writemult*count;
|
||||
timeout = serial->writeconst + (timeout_t)serial->writemult*count;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((async = fd_queue_async( fd, data, type, count )))
|
||||
{
|
||||
if (timeout)
|
||||
{
|
||||
struct timeval when = current_time;
|
||||
add_timeout( &when, timeout );
|
||||
async_set_timeout( async, &when, STATUS_TIMEOUT );
|
||||
}
|
||||
if (timeout) async_set_timeout( async, timeout * -10000, STATUS_TIMEOUT );
|
||||
release_object( async );
|
||||
set_error( STATUS_PENDING );
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ struct thread_wait
|
|||
int count; /* count of objects */
|
||||
int flags;
|
||||
void *cookie; /* magic cookie to return to client */
|
||||
struct timeval timeout;
|
||||
timeout_t timeout;
|
||||
struct timeout_user *user;
|
||||
struct wait_queue_entry queues[1];
|
||||
};
|
||||
|
@ -171,7 +171,7 @@ static inline void init_thread_structure( struct thread *thread )
|
|||
thread->token = NULL;
|
||||
|
||||
thread->creation_time = current_time;
|
||||
thread->exit_time.tv_sec = thread->exit_time.tv_usec = 0;
|
||||
thread->exit_time = 0;
|
||||
|
||||
list_init( &thread->mutex_list );
|
||||
list_init( &thread->system_apc );
|
||||
|
@ -461,24 +461,20 @@ static void end_wait( struct thread *thread )
|
|||
}
|
||||
|
||||
/* build the thread wait structure */
|
||||
static int wait_on( int count, struct object *objects[], int flags, const abs_time_t *timeout )
|
||||
static int wait_on( unsigned int count, struct object *objects[], int flags, timeout_t timeout )
|
||||
{
|
||||
struct thread_wait *wait;
|
||||
struct wait_queue_entry *entry;
|
||||
int i;
|
||||
unsigned int i;
|
||||
|
||||
if (!(wait = mem_alloc( sizeof(*wait) + (count-1) * sizeof(*entry) ))) return 0;
|
||||
if (!(wait = mem_alloc( FIELD_OFFSET(struct thread_wait, queues[count]) ))) return 0;
|
||||
wait->next = current->wait;
|
||||
wait->thread = current;
|
||||
wait->count = count;
|
||||
wait->flags = flags;
|
||||
wait->user = NULL;
|
||||
wait->timeout = timeout;
|
||||
current->wait = wait;
|
||||
if (flags & SELECT_TIMEOUT)
|
||||
{
|
||||
wait->timeout.tv_sec = timeout->sec;
|
||||
wait->timeout.tv_usec = timeout->usec;
|
||||
}
|
||||
|
||||
for (i = 0, entry = wait->queues; i < count; i++, entry++)
|
||||
{
|
||||
|
@ -541,10 +537,7 @@ static int check_wait( struct thread *thread )
|
|||
other_checks:
|
||||
if ((wait->flags & SELECT_INTERRUPTIBLE) && !list_empty(&thread->system_apc)) return STATUS_USER_APC;
|
||||
if ((wait->flags & SELECT_ALERTABLE) && !list_empty(&thread->user_apc)) return STATUS_USER_APC;
|
||||
if (wait->flags & SELECT_TIMEOUT)
|
||||
{
|
||||
if (!time_before( ¤t_time, &wait->timeout )) return STATUS_TIMEOUT;
|
||||
}
|
||||
if (wait->timeout <= current_time) return STATUS_TIMEOUT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -623,16 +616,19 @@ static int signal_object( obj_handle_t handle )
|
|||
}
|
||||
|
||||
/* select on a list of handles */
|
||||
static void select_on( int count, void *cookie, const obj_handle_t *handles,
|
||||
int flags, const abs_time_t *timeout, obj_handle_t signal_obj )
|
||||
static timeout_t select_on( unsigned int count, void *cookie, const obj_handle_t *handles,
|
||||
int flags, timeout_t timeout, obj_handle_t signal_obj )
|
||||
{
|
||||
int ret, i;
|
||||
int ret;
|
||||
unsigned int i;
|
||||
struct object *objects[MAXIMUM_WAIT_OBJECTS];
|
||||
|
||||
if ((count < 0) || (count > MAXIMUM_WAIT_OBJECTS))
|
||||
if (timeout <= 0) timeout = current_time - timeout;
|
||||
|
||||
if (count > MAXIMUM_WAIT_OBJECTS)
|
||||
{
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
|
@ -664,9 +660,9 @@ static void select_on( int count, void *cookie, const obj_handle_t *handles,
|
|||
}
|
||||
|
||||
/* now we need to wait */
|
||||
if (flags & SELECT_TIMEOUT)
|
||||
if (current->wait->timeout != TIMEOUT_INFINITE)
|
||||
{
|
||||
if (!(current->wait->user = add_timeout_user( ¤t->wait->timeout,
|
||||
if (!(current->wait->user = add_timeout_user( current->wait->timeout,
|
||||
thread_timeout, current->wait )))
|
||||
{
|
||||
end_wait( current );
|
||||
|
@ -677,7 +673,8 @@ static void select_on( int count, void *cookie, const obj_handle_t *handles,
|
|||
set_error( STATUS_PENDING );
|
||||
|
||||
done:
|
||||
while (--i >= 0) release_object( objects[i] );
|
||||
while (i > 0) release_object( objects[--i] );
|
||||
return timeout;
|
||||
}
|
||||
|
||||
/* attempt to wake threads sleeping on the object wait queue */
|
||||
|
@ -1035,8 +1032,7 @@ DECL_HANDLER(init_thread)
|
|||
reply->pid = get_process_id( process );
|
||||
reply->tid = get_thread_id( current );
|
||||
reply->version = SERVER_PROTOCOL_VERSION;
|
||||
reply->server_start.sec = server_start_time.tv_sec;
|
||||
reply->server_start.usec = server_start_time.tv_usec;
|
||||
reply->server_start = server_start_time;
|
||||
return;
|
||||
|
||||
error:
|
||||
|
@ -1094,10 +1090,8 @@ DECL_HANDLER(get_thread_info)
|
|||
reply->exit_code = (thread->state == TERMINATED) ? thread->exit_code : STATUS_PENDING;
|
||||
reply->priority = thread->priority;
|
||||
reply->affinity = thread->affinity;
|
||||
reply->creation_time.sec = thread->creation_time.tv_sec;
|
||||
reply->creation_time.usec = thread->creation_time.tv_usec;
|
||||
reply->exit_time.sec = thread->exit_time.tv_sec;
|
||||
reply->exit_time.usec = thread->exit_time.tv_usec;
|
||||
reply->creation_time = thread->creation_time;
|
||||
reply->exit_time = thread->exit_time;
|
||||
reply->last = thread->process->running_threads == 1;
|
||||
|
||||
release_object( thread );
|
||||
|
@ -1145,8 +1139,8 @@ DECL_HANDLER(resume_thread)
|
|||
/* select on a handle list */
|
||||
DECL_HANDLER(select)
|
||||
{
|
||||
int count = get_req_data_size() / sizeof(obj_handle_t);
|
||||
select_on( count, req->cookie, get_req_data(), req->flags, &req->timeout, req->signal );
|
||||
unsigned int count = get_req_data_size() / sizeof(obj_handle_t);
|
||||
reply->timeout = select_on( count, req->cookie, get_req_data(), req->flags, req->timeout, req->signal );
|
||||
}
|
||||
|
||||
/* queue an APC for a thread or process */
|
||||
|
|
|
@ -84,8 +84,8 @@ struct thread
|
|||
int suspend; /* suspend count */
|
||||
obj_handle_t desktop; /* desktop handle */
|
||||
int desktop_users; /* number of objects using the thread desktop */
|
||||
struct timeval creation_time; /* Thread creation time */
|
||||
struct timeval exit_time; /* Thread exit time */
|
||||
timeout_t creation_time; /* Thread creation time */
|
||||
timeout_t exit_time; /* Thread exit time */
|
||||
struct token *token; /* security token associated with this thread */
|
||||
};
|
||||
|
||||
|
|
|
@ -42,8 +42,8 @@ struct timer
|
|||
struct object obj; /* object header */
|
||||
int manual; /* manual reset */
|
||||
int signaled; /* current signaled state */
|
||||
int period; /* timer period in ms */
|
||||
struct timeval when; /* next expiration */
|
||||
unsigned int period; /* timer period in ms */
|
||||
timeout_t when; /* next expiration */
|
||||
struct timeout_user *timeout; /* timeout user */
|
||||
struct thread *thread; /* thread that set the APC function */
|
||||
void *callback; /* callback APC function */
|
||||
|
@ -85,13 +85,12 @@ static struct timer *create_timer( struct directory *root, const struct unicode_
|
|||
if (get_error() != STATUS_OBJECT_NAME_EXISTS)
|
||||
{
|
||||
/* initialize it if it didn't already exist */
|
||||
timer->manual = manual;
|
||||
timer->signaled = 0;
|
||||
timer->when.tv_sec = 0;
|
||||
timer->when.tv_usec = 0;
|
||||
timer->period = 0;
|
||||
timer->timeout = NULL;
|
||||
timer->thread = NULL;
|
||||
timer->manual = manual;
|
||||
timer->signaled = 0;
|
||||
timer->when = 0;
|
||||
timer->period = 0;
|
||||
timer->timeout = NULL;
|
||||
timer->thread = NULL;
|
||||
}
|
||||
}
|
||||
return timer;
|
||||
|
@ -110,11 +109,10 @@ static void timer_callback( void *private )
|
|||
memset( &data, 0, sizeof(data) );
|
||||
if (timer->callback)
|
||||
{
|
||||
data.type = APC_TIMER;
|
||||
data.timer.func = timer->callback;
|
||||
data.timer.time.sec = timer->when.tv_sec;
|
||||
data.timer.time.usec = timer->when.tv_usec;
|
||||
data.timer.arg = timer->arg;
|
||||
data.type = APC_TIMER;
|
||||
data.timer.func = timer->callback;
|
||||
data.timer.time = timer->when;
|
||||
data.timer.arg = timer->arg;
|
||||
}
|
||||
else data.type = APC_NONE; /* wake up only */
|
||||
|
||||
|
@ -127,8 +125,8 @@ static void timer_callback( void *private )
|
|||
|
||||
if (timer->period) /* schedule the next expiration */
|
||||
{
|
||||
add_timeout( &timer->when, timer->period );
|
||||
timer->timeout = add_timeout_user( &timer->when, timer_callback, timer );
|
||||
timer->when += (timeout_t)timer->period * 10000;
|
||||
timer->timeout = add_timeout_user( timer->when, timer_callback, timer );
|
||||
}
|
||||
else timer->timeout = NULL;
|
||||
|
||||
|
@ -157,7 +155,7 @@ static int cancel_timer( struct timer *timer )
|
|||
}
|
||||
|
||||
/* set the timer expiration and period */
|
||||
static int set_timer( struct timer *timer, const abs_time_t *expire, int period,
|
||||
static int set_timer( struct timer *timer, timeout_t expire, unsigned int period,
|
||||
void *callback, void *arg )
|
||||
{
|
||||
int signaled = cancel_timer( timer );
|
||||
|
@ -166,22 +164,12 @@ static int set_timer( struct timer *timer, const abs_time_t *expire, int period,
|
|||
period = 0; /* period doesn't make any sense for a manual timer */
|
||||
timer->signaled = 0;
|
||||
}
|
||||
if (!expire->sec && !expire->usec)
|
||||
{
|
||||
/* special case: use now + period as first expiration */
|
||||
timer->when = current_time;
|
||||
add_timeout( &timer->when, period );
|
||||
}
|
||||
else
|
||||
{
|
||||
timer->when.tv_sec = expire->sec;
|
||||
timer->when.tv_usec = expire->usec;
|
||||
}
|
||||
timer->period = period;
|
||||
timer->callback = callback;
|
||||
timer->arg = arg;
|
||||
|
||||
timer->period = period;
|
||||
timer->callback = callback;
|
||||
timer->arg = arg;
|
||||
if (callback) timer->thread = (struct thread *)grab_object( current );
|
||||
timer->timeout = add_timeout_user( &timer->when, timer_callback, timer );
|
||||
timer->timeout = add_timeout_user( timer->when, timer_callback, timer );
|
||||
return signaled;
|
||||
}
|
||||
|
||||
|
@ -189,8 +177,8 @@ static void timer_dump( struct object *obj, int verbose )
|
|||
{
|
||||
struct timer *timer = (struct timer *)obj;
|
||||
assert( obj->ops == &timer_ops );
|
||||
fprintf( stderr, "Timer manual=%d when=%ld.%06u period=%d ",
|
||||
timer->manual, timer->when.tv_sec, (unsigned int)timer->when.tv_usec, timer->period );
|
||||
fprintf( stderr, "Timer manual=%d when=%s period=%u ",
|
||||
timer->manual, get_timeout_str(timer->when), timer->period );
|
||||
dump_object_name( &timer->obj );
|
||||
fputc( '\n', stderr );
|
||||
}
|
||||
|
@ -277,7 +265,7 @@ DECL_HANDLER(set_timer)
|
|||
if ((timer = (struct timer *)get_handle_obj( current->process, req->handle,
|
||||
TIMER_MODIFY_STATE, &timer_ops )))
|
||||
{
|
||||
reply->signaled = set_timer( timer, &req->expire, req->period, req->callback, req->arg );
|
||||
reply->signaled = set_timer( timer, req->expire, req->period, req->callback, req->arg );
|
||||
release_object( timer );
|
||||
}
|
||||
}
|
||||
|
@ -303,8 +291,7 @@ DECL_HANDLER(get_timer_info)
|
|||
if ((timer = (struct timer *)get_handle_obj( current->process, req->handle,
|
||||
TIMER_QUERY_STATE, &timer_ops )))
|
||||
{
|
||||
reply->when.sec = timer->when.tv_sec;
|
||||
reply->when.usec = timer->when.tv_usec;
|
||||
reply->when = timer->when;
|
||||
reply->signaled = timer->signaled;
|
||||
release_object( timer );
|
||||
}
|
||||
|
|
|
@ -64,25 +64,9 @@ static void dump_uints( const int *ptr, int len )
|
|||
fputc( '}', stderr );
|
||||
}
|
||||
|
||||
static void dump_abs_time( const abs_time_t *time )
|
||||
static void dump_timeout( const timeout_t *time )
|
||||
{
|
||||
int secs, usecs;
|
||||
|
||||
if (!time->sec && !time->usec)
|
||||
{
|
||||
fprintf( stderr, "0" );
|
||||
return;
|
||||
}
|
||||
secs = time->sec - current_time.tv_sec;
|
||||
if ((usecs = time->usec - current_time.tv_usec) < 0)
|
||||
{
|
||||
usecs += 1000000;
|
||||
secs--;
|
||||
}
|
||||
if (secs > 0 || (secs == 0 && usecs >= 0))
|
||||
fprintf( stderr, "%d.%06d (+%d.%06d)", time->sec, time->usec, secs, usecs );
|
||||
else
|
||||
fprintf( stderr, "%d.%06d (-%d.%06d)", time->sec, time->usec, abs(secs+1), 1000000-usecs );
|
||||
fprintf( stderr, get_timeout_str(*time) );
|
||||
}
|
||||
|
||||
static void dump_rectangle( const rectangle_t *rect )
|
||||
|
@ -112,7 +96,7 @@ static void dump_apc_call( const apc_call_t *call )
|
|||
break;
|
||||
case APC_TIMER:
|
||||
fprintf( stderr, "APC_TIMER,time=" );
|
||||
dump_abs_time( &call->timer.time );
|
||||
dump_timeout( &call->timer.time );
|
||||
fprintf( stderr, ",arg=%p", call->timer.arg );
|
||||
break;
|
||||
case APC_ASYNC_IO:
|
||||
|
@ -862,7 +846,7 @@ static void dump_init_thread_reply( const struct init_thread_reply *req )
|
|||
fprintf( stderr, " tid=%04x,", req->tid );
|
||||
fprintf( stderr, " info_size=%u,", req->info_size );
|
||||
fprintf( stderr, " server_start=" );
|
||||
dump_abs_time( &req->server_start );
|
||||
dump_timeout( &req->server_start );
|
||||
fprintf( stderr, "," );
|
||||
fprintf( stderr, " version=%d", req->version );
|
||||
}
|
||||
|
@ -904,10 +888,10 @@ static void dump_get_process_info_reply( const struct get_process_info_reply *re
|
|||
fprintf( stderr, " affinity=%d,", req->affinity );
|
||||
fprintf( stderr, " peb=%p,", req->peb );
|
||||
fprintf( stderr, " start_time=" );
|
||||
dump_abs_time( &req->start_time );
|
||||
dump_timeout( &req->start_time );
|
||||
fprintf( stderr, "," );
|
||||
fprintf( stderr, " end_time=" );
|
||||
dump_abs_time( &req->end_time );
|
||||
dump_timeout( &req->end_time );
|
||||
}
|
||||
|
||||
static void dump_set_process_info_request( const struct set_process_info_request *req )
|
||||
|
@ -933,10 +917,10 @@ static void dump_get_thread_info_reply( const struct get_thread_info_reply *req
|
|||
fprintf( stderr, " priority=%d,", req->priority );
|
||||
fprintf( stderr, " affinity=%d,", req->affinity );
|
||||
fprintf( stderr, " creation_time=" );
|
||||
dump_abs_time( &req->creation_time );
|
||||
dump_timeout( &req->creation_time );
|
||||
fprintf( stderr, "," );
|
||||
fprintf( stderr, " exit_time=" );
|
||||
dump_abs_time( &req->exit_time );
|
||||
dump_timeout( &req->exit_time );
|
||||
fprintf( stderr, "," );
|
||||
fprintf( stderr, " last=%d", req->last );
|
||||
}
|
||||
|
@ -1105,12 +1089,18 @@ static void dump_select_request( const struct select_request *req )
|
|||
fprintf( stderr, " cookie=%p,", req->cookie );
|
||||
fprintf( stderr, " signal=%p,", req->signal );
|
||||
fprintf( stderr, " timeout=" );
|
||||
dump_abs_time( &req->timeout );
|
||||
dump_timeout( &req->timeout );
|
||||
fprintf( stderr, "," );
|
||||
fprintf( stderr, " handles=" );
|
||||
dump_varargs_handles( cur_size );
|
||||
}
|
||||
|
||||
static void dump_select_reply( const struct select_reply *req )
|
||||
{
|
||||
fprintf( stderr, " timeout=" );
|
||||
dump_timeout( &req->timeout );
|
||||
}
|
||||
|
||||
static void dump_create_event_request( const struct create_event_request *req )
|
||||
{
|
||||
fprintf( stderr, " access=%08x,", req->access );
|
||||
|
@ -2056,7 +2046,7 @@ static void dump_set_timer_request( const struct set_timer_request *req )
|
|||
{
|
||||
fprintf( stderr, " handle=%p,", req->handle );
|
||||
fprintf( stderr, " expire=" );
|
||||
dump_abs_time( &req->expire );
|
||||
dump_timeout( &req->expire );
|
||||
fprintf( stderr, "," );
|
||||
fprintf( stderr, " period=%d,", req->period );
|
||||
fprintf( stderr, " callback=%p,", req->callback );
|
||||
|
@ -2086,7 +2076,7 @@ static void dump_get_timer_info_request( const struct get_timer_info_request *re
|
|||
static void dump_get_timer_info_reply( const struct get_timer_info_reply *req )
|
||||
{
|
||||
fprintf( stderr, " when=" );
|
||||
dump_abs_time( &req->when );
|
||||
dump_timeout( &req->when );
|
||||
fprintf( stderr, "," );
|
||||
fprintf( stderr, " signaled=%d", req->signaled );
|
||||
}
|
||||
|
@ -2257,7 +2247,9 @@ static void dump_send_message_request( const struct send_message_request *req )
|
|||
fprintf( stderr, " msg=%08x,", req->msg );
|
||||
fprintf( stderr, " wparam=%lx,", req->wparam );
|
||||
fprintf( stderr, " lparam=%lx,", req->lparam );
|
||||
fprintf( stderr, " timeout=%d,", req->timeout );
|
||||
fprintf( stderr, " timeout=" );
|
||||
dump_timeout( &req->timeout );
|
||||
fprintf( stderr, "," );
|
||||
fprintf( stderr, " data=" );
|
||||
dump_varargs_message_data( cur_size );
|
||||
}
|
||||
|
@ -2423,7 +2415,9 @@ static void dump_create_named_pipe_request( const struct create_named_pipe_reque
|
|||
fprintf( stderr, " maxinstances=%08x,", req->maxinstances );
|
||||
fprintf( stderr, " outsize=%08x,", req->outsize );
|
||||
fprintf( stderr, " insize=%08x,", req->insize );
|
||||
fprintf( stderr, " timeout=%08x,", req->timeout );
|
||||
fprintf( stderr, " timeout=" );
|
||||
dump_timeout( &req->timeout );
|
||||
fprintf( stderr, "," );
|
||||
fprintf( stderr, " name=" );
|
||||
dump_varargs_unicode_str( cur_size );
|
||||
}
|
||||
|
@ -2446,7 +2440,9 @@ static void dump_wait_named_pipe_request( const struct wait_named_pipe_request *
|
|||
fprintf( stderr, " async=" );
|
||||
dump_async_data( &req->async );
|
||||
fprintf( stderr, "," );
|
||||
fprintf( stderr, " timeout=%08x,", req->timeout );
|
||||
fprintf( stderr, " timeout=" );
|
||||
dump_timeout( &req->timeout );
|
||||
fprintf( stderr, "," );
|
||||
fprintf( stderr, " name=" );
|
||||
dump_varargs_unicode_str( cur_size );
|
||||
}
|
||||
|
@ -3336,7 +3332,9 @@ static void dump_create_mailslot_request( const struct create_mailslot_request *
|
|||
fprintf( stderr, " attributes=%08x,", req->attributes );
|
||||
fprintf( stderr, " rootdir=%p,", req->rootdir );
|
||||
fprintf( stderr, " max_msgsize=%08x,", req->max_msgsize );
|
||||
fprintf( stderr, " read_timeout=%d,", req->read_timeout );
|
||||
fprintf( stderr, " read_timeout=" );
|
||||
dump_timeout( &req->read_timeout );
|
||||
fprintf( stderr, "," );
|
||||
fprintf( stderr, " name=" );
|
||||
dump_varargs_unicode_str( cur_size );
|
||||
}
|
||||
|
@ -3350,13 +3348,15 @@ static void dump_set_mailslot_info_request( const struct set_mailslot_info_reque
|
|||
{
|
||||
fprintf( stderr, " handle=%p,", req->handle );
|
||||
fprintf( stderr, " flags=%08x,", req->flags );
|
||||
fprintf( stderr, " read_timeout=%d", req->read_timeout );
|
||||
fprintf( stderr, " read_timeout=" );
|
||||
dump_timeout( &req->read_timeout );
|
||||
}
|
||||
|
||||
static void dump_set_mailslot_info_reply( const struct set_mailslot_info_reply *req )
|
||||
{
|
||||
fprintf( stderr, " max_msgsize=%08x,", req->max_msgsize );
|
||||
fprintf( stderr, " read_timeout=%d", req->read_timeout );
|
||||
fprintf( stderr, " read_timeout=" );
|
||||
dump_timeout( &req->read_timeout );
|
||||
}
|
||||
|
||||
static void dump_create_directory_request( const struct create_directory_request *req )
|
||||
|
@ -3706,7 +3706,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
|
|||
(dump_func)dump_dup_handle_reply,
|
||||
(dump_func)dump_open_process_reply,
|
||||
(dump_func)dump_open_thread_reply,
|
||||
(dump_func)0,
|
||||
(dump_func)dump_select_reply,
|
||||
(dump_func)dump_create_event_reply,
|
||||
(dump_func)0,
|
||||
(dump_func)dump_open_event_reply,
|
||||
|
|
|
@ -363,10 +363,8 @@ void close_process_desktop( struct process *process )
|
|||
/* if we have one remaining user, it has to be the manager of the desktop window */
|
||||
if (desktop->users == 1 && get_top_window_owner( desktop ))
|
||||
{
|
||||
struct timeval when = current_time;
|
||||
add_timeout( &when, 1000 );
|
||||
assert( !desktop->close_timeout );
|
||||
desktop->close_timeout = add_timeout_user( &when, close_desktop_timeout, desktop );
|
||||
desktop->close_timeout = add_timeout_user( -TICKS_PER_SEC, close_desktop_timeout, desktop );
|
||||
}
|
||||
release_object( desktop );
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ my %formats =
|
|||
"user_handle_t" => "%p",
|
||||
"process_id_t" => "%04x",
|
||||
"thread_id_t" => "%04x",
|
||||
"abs_time_t" => "&dump_abs_time",
|
||||
"timeout_t" => "&dump_timeout",
|
||||
"rectangle_t" => "&dump_rectangle",
|
||||
"char_info_t" => "&dump_char_info",
|
||||
"apc_call_t" => "&dump_apc_call",
|
||||
|
|
Loading…
Reference in New Issue