mirror of https://github.com/reactos/reactos.git
Diverge a little less
This commit is contained in:
parent
4f67f4c53d
commit
53cc6a8c04
|
@ -1312,7 +1312,7 @@
|
|||
@ stub -version=0x600+ ShipAssertMsgW
|
||||
@ stub -version=0x600+ TpAllocAlpcCompletion
|
||||
@ stdcall -version=0x600+ TpAllocCleanupGroup(ptr)
|
||||
@ stub -version=0x600+ TpAllocIoCompletion
|
||||
@ stdcall -version=0x600+ TpAllocIoCompletion(ptr ptr ptr ptr ptr)
|
||||
@ stdcall -version=0x600+ TpAllocPool(ptr ptr)
|
||||
@ stdcall -version=0x600+ TpAllocTimer(ptr ptr ptr ptr)
|
||||
@ stdcall -version=0x600+ TpAllocWait(ptr ptr ptr ptr)
|
||||
|
@ -1323,7 +1323,7 @@
|
|||
@ stdcall -version=0x600+ TpCallbackReleaseSemaphoreOnCompletion(ptr ptr long)
|
||||
@ stdcall -version=0x600+ TpCallbackSetEventOnCompletion(ptr ptr)
|
||||
@ stdcall -version=0x600+ TpCallbackUnloadDllOnCompletion(ptr ptr)
|
||||
@ stub -version=0x600+ TpCancelAsyncIoOperation
|
||||
@ stdcall -version=0x600+ TpCancelAsyncIoOperation(ptr)
|
||||
@ stub -version=0x600+ TpCaptureCaller
|
||||
@ stub -version=0x600+ TpCheckTerminateWorker
|
||||
@ stub -version=0x600+ TpDbgDumpHeapUsage
|
||||
|
@ -1334,7 +1334,7 @@
|
|||
@ stub -version=0x600+ TpReleaseAlpcCompletion
|
||||
@ stdcall -version=0x600+ TpReleaseCleanupGroup(ptr)
|
||||
@ stdcall -version=0x600+ TpReleaseCleanupGroupMembers(ptr long ptr)
|
||||
@ stub -version=0x600+ TpReleaseIoCompletion
|
||||
@ stdcall -version=0x600+ TpReleaseIoCompletion(ptr)
|
||||
@ stdcall -version=0x600+ TpReleasePool(ptr)
|
||||
@ stdcall -version=0x600+ TpReleaseTimer(ptr)
|
||||
@ stdcall -version=0x600+ TpReleaseWait(ptr)
|
||||
|
@ -1344,9 +1344,9 @@
|
|||
@ stdcall -version=0x600+ TpSetTimer(ptr ptr long long)
|
||||
@ stdcall -version=0x600+ TpSetWait(ptr long ptr)
|
||||
@ stdcall -version=0x600+ TpSimpleTryPost(ptr ptr ptr)
|
||||
@ stub -version=0x600+ TpStartAsyncIoOperation
|
||||
@ stdcall -version=0x600+ TpStartAsyncIoOperation(ptr)
|
||||
@ stub -version=0x600+ TpWaitForAlpcCompletion
|
||||
@ stub -version=0x600+ TpWaitForIoCompletion
|
||||
@ stdcall -version=0x600+ TpWaitForIoCompletion(ptr long)
|
||||
@ stdcall -version=0x600+ TpWaitForTimer(ptr long)
|
||||
@ stdcall -version=0x600+ TpWaitForWait(ptr long)
|
||||
@ stdcall -version=0x600+ TpWaitForWork(ptr long)
|
||||
|
|
|
@ -10,8 +10,6 @@ if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
|||
add_compile_options(-Wunused-result)
|
||||
endif()
|
||||
|
||||
include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine)
|
||||
|
||||
list(APPEND SOURCE
|
||||
access.c
|
||||
acl.c
|
||||
|
|
|
@ -512,7 +512,7 @@ NTSTATUS
|
|||
NTAPI
|
||||
RtlSleepConditionVariableSRW(IN OUT PRTL_CONDITION_VARIABLE ConditionVariable,
|
||||
IN OUT PRTL_SRWLOCK SRWLock,
|
||||
IN const PLARGE_INTEGER TimeOut OPTIONAL,
|
||||
IN PLARGE_INTEGER TimeOut OPTIONAL,
|
||||
IN ULONG Flags)
|
||||
{
|
||||
return InternalSleep(ConditionVariable,
|
||||
|
|
|
@ -48,6 +48,8 @@ typedef void (CALLBACK *PTP_IO_CALLBACK)(PTP_CALLBACK_INSTANCE,void*,void*,IO_ST
|
|||
NTSYSAPI NTSTATUS WINAPI TpSimpleTryPost(PTP_SIMPLE_CALLBACK,PVOID,TP_CALLBACK_ENVIRON *);
|
||||
|
||||
// Redefines
|
||||
#define PRTL_WORK_ITEM_ROUTINE WORKERCALLBACKFUNC
|
||||
|
||||
#define CRITICAL_SECTION RTL_CRITICAL_SECTION
|
||||
#define GetProcessHeap() RtlGetProcessHeap()
|
||||
#define GetCurrentProcess() NtCurrentProcess()
|
||||
|
@ -477,11 +479,7 @@ static void CALLBACK process_rtl_work_item( TP_CALLBACK_INSTANCE *instance, void
|
|||
*|WT_EXECUTELONGFUNCTION - Hints that the execution can take a long time.
|
||||
*|WT_TRANSFER_IMPERSONATION - Executes the function with the current access token.
|
||||
*/
|
||||
#ifdef __REACTOS__
|
||||
NTSTATUS WINAPI RtlQueueWorkItem( WORKERCALLBACKFUNC function, PVOID context, ULONG flags )
|
||||
#else
|
||||
NTSTATUS WINAPI RtlQueueWorkItem( PRTL_WORK_ITEM_ROUTINE function, PVOID context, ULONG flags )
|
||||
#endif
|
||||
{
|
||||
TP_CALLBACK_ENVIRON environment;
|
||||
struct rtl_work_item *item;
|
||||
|
@ -499,7 +497,7 @@ NTSTATUS WINAPI RtlQueueWorkItem( PRTL_WORK_ITEM_ROUTINE function, PVOID context
|
|||
environment.u.s.Persistent = (flags & WT_EXECUTEINPERSISTENTTHREAD) != 0;
|
||||
|
||||
#ifdef __REACTOS__
|
||||
item->function = (PRTL_WORK_ITEM_ROUTINE)function;
|
||||
item->function = function;
|
||||
#else
|
||||
item->function = function;
|
||||
#endif
|
||||
|
|
|
@ -64,197 +64,6 @@ struct timer_queue
|
|||
#define EXPIRE_NEVER (~(ULONGLONG) 0)
|
||||
#define TIMER_QUEUE_MAGIC 0x516d6954 /* TimQ */
|
||||
|
||||
static void queue_remove_timer(struct queue_timer *t)
|
||||
{
|
||||
/* We MUST hold the queue cs while calling this function. This ensures
|
||||
that we cannot queue another callback for this timer. The runcount
|
||||
being zero makes sure we don't have any already queued. */
|
||||
struct timer_queue *q = t->q;
|
||||
|
||||
assert(t->runcount == 0);
|
||||
assert(t->destroy);
|
||||
|
||||
list_remove(&t->entry);
|
||||
if (t->event)
|
||||
NtSetEvent(t->event, NULL);
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, t);
|
||||
|
||||
if (q->quit && list_empty(&q->timers))
|
||||
NtSetEvent(q->event, NULL);
|
||||
}
|
||||
|
||||
static void timer_cleanup_callback(struct queue_timer *t)
|
||||
{
|
||||
struct timer_queue *q = t->q;
|
||||
RtlEnterCriticalSection(&q->cs);
|
||||
|
||||
assert(0 < t->runcount);
|
||||
--t->runcount;
|
||||
|
||||
if (t->destroy && t->runcount == 0)
|
||||
queue_remove_timer(t);
|
||||
|
||||
RtlLeaveCriticalSection(&q->cs);
|
||||
}
|
||||
|
||||
static VOID WINAPI timer_callback_wrapper(LPVOID p)
|
||||
{
|
||||
struct queue_timer *t = p;
|
||||
t->callback(t->param, TRUE);
|
||||
timer_cleanup_callback(t);
|
||||
}
|
||||
|
||||
static inline ULONGLONG queue_current_time(void)
|
||||
{
|
||||
LARGE_INTEGER now, freq;
|
||||
NtQueryPerformanceCounter(&now, &freq);
|
||||
return now.QuadPart * 1000 / freq.QuadPart;
|
||||
}
|
||||
|
||||
static void queue_add_timer(struct queue_timer *t, ULONGLONG time,
|
||||
BOOL set_event)
|
||||
{
|
||||
/* We MUST hold the queue cs while calling this function. */
|
||||
struct timer_queue *q = t->q;
|
||||
struct list *ptr = &q->timers;
|
||||
|
||||
assert(!q->quit || (t->destroy && time == EXPIRE_NEVER));
|
||||
|
||||
if (time != EXPIRE_NEVER)
|
||||
LIST_FOR_EACH(ptr, &q->timers)
|
||||
{
|
||||
struct queue_timer *cur = LIST_ENTRY(ptr, struct queue_timer, entry);
|
||||
if (time < cur->expire)
|
||||
break;
|
||||
}
|
||||
list_add_before(ptr, &t->entry);
|
||||
|
||||
t->expire = time;
|
||||
|
||||
/* If we insert at the head of the list, we need to expire sooner
|
||||
than expected. */
|
||||
if (set_event && &t->entry == list_head(&q->timers))
|
||||
NtSetEvent(q->event, NULL);
|
||||
}
|
||||
|
||||
static inline void queue_move_timer(struct queue_timer *t, ULONGLONG time,
|
||||
BOOL set_event)
|
||||
{
|
||||
/* We MUST hold the queue cs while calling this function. */
|
||||
list_remove(&t->entry);
|
||||
queue_add_timer(t, time, set_event);
|
||||
}
|
||||
|
||||
static void queue_timer_expire(struct timer_queue *q)
|
||||
{
|
||||
struct queue_timer *t = NULL;
|
||||
|
||||
RtlEnterCriticalSection(&q->cs);
|
||||
if (list_head(&q->timers))
|
||||
{
|
||||
ULONGLONG now, next;
|
||||
t = LIST_ENTRY(list_head(&q->timers), struct queue_timer, entry);
|
||||
if (!t->destroy && t->expire <= ((now = queue_current_time())))
|
||||
{
|
||||
++t->runcount;
|
||||
if (t->period)
|
||||
{
|
||||
next = t->expire + t->period;
|
||||
/* avoid trigger cascade if overloaded / hibernated */
|
||||
if (next < now)
|
||||
next = now + t->period;
|
||||
}
|
||||
else
|
||||
next = EXPIRE_NEVER;
|
||||
queue_move_timer(t, next, FALSE);
|
||||
}
|
||||
else
|
||||
t = NULL;
|
||||
}
|
||||
RtlLeaveCriticalSection(&q->cs);
|
||||
|
||||
if (t)
|
||||
{
|
||||
if (t->flags & WT_EXECUTEINTIMERTHREAD)
|
||||
timer_callback_wrapper(t);
|
||||
else
|
||||
{
|
||||
ULONG flags
|
||||
= (t->flags
|
||||
& (WT_EXECUTEINIOTHREAD | WT_EXECUTEINPERSISTENTTHREAD
|
||||
| WT_EXECUTELONGFUNCTION | WT_TRANSFER_IMPERSONATION));
|
||||
NTSTATUS status = RtlQueueWorkItem(timer_callback_wrapper, t, flags);
|
||||
if (status != STATUS_SUCCESS)
|
||||
timer_cleanup_callback(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static ULONG queue_get_timeout(struct timer_queue *q)
|
||||
{
|
||||
struct queue_timer *t;
|
||||
ULONG timeout = INFINITE;
|
||||
|
||||
RtlEnterCriticalSection(&q->cs);
|
||||
if (list_head(&q->timers))
|
||||
{
|
||||
t = LIST_ENTRY(list_head(&q->timers), struct queue_timer, entry);
|
||||
assert(!t->destroy || t->expire == EXPIRE_NEVER);
|
||||
|
||||
if (t->expire != EXPIRE_NEVER)
|
||||
{
|
||||
ULONGLONG time = queue_current_time();
|
||||
timeout = t->expire < time ? 0 : (ULONG)(t->expire - time);
|
||||
}
|
||||
}
|
||||
RtlLeaveCriticalSection(&q->cs);
|
||||
|
||||
return timeout;
|
||||
}
|
||||
|
||||
static DWORD WINAPI timer_queue_thread_proc(LPVOID p)
|
||||
{
|
||||
struct timer_queue *q = p;
|
||||
ULONG timeout_ms;
|
||||
|
||||
timeout_ms = INFINITE;
|
||||
for (;;)
|
||||
{
|
||||
LARGE_INTEGER timeout;
|
||||
NTSTATUS status;
|
||||
BOOL done = FALSE;
|
||||
|
||||
status = NtWaitForSingleObject(
|
||||
q->event, FALSE, get_nt_timeout(&timeout, timeout_ms));
|
||||
|
||||
if (status == STATUS_WAIT_0)
|
||||
{
|
||||
/* There are two possible ways to trigger the event. Either
|
||||
we are quitting and the last timer got removed, or a new
|
||||
timer got put at the head of the list so we need to adjust
|
||||
our timeout. */
|
||||
RtlEnterCriticalSection(&q->cs);
|
||||
if (q->quit && list_empty(&q->timers))
|
||||
done = TRUE;
|
||||
RtlLeaveCriticalSection(&q->cs);
|
||||
}
|
||||
else if (status == STATUS_TIMEOUT)
|
||||
queue_timer_expire(q);
|
||||
|
||||
if (done)
|
||||
break;
|
||||
|
||||
timeout_ms = queue_get_timeout(q);
|
||||
}
|
||||
|
||||
NtClose(q->event);
|
||||
RtlDeleteCriticalSection(&q->cs);
|
||||
q->magic = 0;
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, q);
|
||||
RtlpExitThreadFunc(STATUS_SUCCESS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
WINAPI
|
||||
RtlSetTimer(
|
||||
|
|
Loading…
Reference in New Issue