ReactOS 0.4.15-dev-7934-g1dc8d80
runonce.c
Go to the documentation of this file.
1
2/* Taken from Wine ntdll/sync.c */
3
4#include <rtl_vista.h>
5#include <wine/config.h>
6#include <wine/port.h>
7
8/******************************************************************
9 * RtlRunOnceInitialize (NTDLL.@)
10 */
12{
13 RunOnce->Ptr = NULL;
14}
15
16/******************************************************************
17 * RtlRunOnceBeginInitialize (NTDLL.@)
18 */
23 _Inout_ PRTL_RUN_ONCE RunOnce,
26{
28 {
29 ULONG_PTR val = (ULONG_PTR)RunOnce->Ptr;
30
32 if ((val & 3) != 2) return STATUS_UNSUCCESSFUL;
33 if (Context) *Context = (void *)(val & ~3);
34 return STATUS_SUCCESS;
35 }
36
37 for (;;)
38 {
39 ULONG_PTR next, val = (ULONG_PTR)RunOnce->Ptr;
40
41 switch (val & 3)
42 {
43 case 0: /* first time */
44 if (!interlocked_cmpxchg_ptr( &RunOnce->Ptr,
45 (Flags & RTL_RUN_ONCE_ASYNC) ? (void *)3 : (void *)1, 0))
46 return STATUS_PENDING;
47 break;
48
49 case 1: /* in progress, wait */
51 next = val & ~3;
52 if (interlocked_cmpxchg_ptr( &RunOnce->Ptr, (void *)((ULONG_PTR)&next | 1),
53 (void *)val ) == (void *)val)
55 break;
56
57 case 2: /* done */
58 if (Context) *Context = (void *)(val & ~3);
59 return STATUS_SUCCESS;
60
61 case 3: /* in progress, async */
63 return STATUS_PENDING;
64 }
65 }
66}
67
68/******************************************************************
69 * RtlRunOnceComplete (NTDLL.@)
70 */
74 _Inout_ PRTL_RUN_ONCE RunOnce,
77{
79
81 {
84 }
85 else Context = (void *)((ULONG_PTR)Context | 2);
86
87 for (;;)
88 {
89 ULONG_PTR val = (ULONG_PTR)RunOnce->Ptr;
90
91 switch (val & 3)
92 {
93 case 1: /* in progress */
94 if (interlocked_cmpxchg_ptr( &RunOnce->Ptr, Context, (void *)val ) != (void *)val) break;
95 val &= ~3;
96 while (val)
97 {
99 NtReleaseKeyedEvent( 0, (void *)val, FALSE, NULL );
100 val = next;
101 }
102 return STATUS_SUCCESS;
103
104 case 3: /* in progress, async */
106 if (interlocked_cmpxchg_ptr( &RunOnce->Ptr, Context, (void *)val) != (void *)val) break;
107 return STATUS_SUCCESS;
108
109 default:
110 return STATUS_UNSUCCESSFUL;
111 }
112 }
113}
114
115/******************************************************************
116 * RtlRunOnceExecuteOnce (NTDLL.@)
117 */
120NTAPI
122 _Inout_ PRTL_RUN_ONCE RunOnce,
126{
128
129 if (ret != STATUS_PENDING) return ret;
130
131 if (!InitFn( RunOnce, Parameter, Context ))
132 {
134 return STATUS_UNSUCCESSFUL;
135 }
136
137 return RtlRunOnceComplete( RunOnce, 0, Context ? *Context : NULL );
138}
LONG NTSTATUS
Definition: precomp.h:26
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
switch(r->id)
Definition: btrfs.c:3046
#define ULONG_PTR
Definition: config.h:101
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLfloat * val
Definition: glext.h:7180
NTSYSAPI NTSTATUS WINAPI NtWaitForKeyedEvent(HANDLE, const void *, BOOLEAN, const LARGE_INTEGER *)
NTSYSAPI NTSTATUS WINAPI NtReleaseKeyedEvent(HANDLE, const void *, BOOLEAN, const LARGE_INTEGER *)
if(dx< 0)
Definition: linetemp.h:194
#define _Inout_
Definition: ms_sal.h:378
#define _Outptr_opt_result_maybenull_
Definition: ms_sal.h:430
#define __inner_callback
Definition: ms_sal.h:2636
#define _Inout_opt_
Definition: ms_sal.h:379
#define _Must_inspect_result_
Definition: ms_sal.h:558
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
#define _In_opt_
Definition: ms_sal.h:309
#define _Maybe_raises_SEH_exception_
Definition: ms_sal.h:2956
#define STATUS_PENDING
Definition: ntstatus.h:82
static unsigned __int64 next
Definition: rand_nt.c:6
#define interlocked_cmpxchg_ptr
Definition: port.h:344
VOID NTAPI RtlRunOnceInitialize(_Out_ PRTL_RUN_ONCE RunOnce)
Definition: runonce.c:11
_Maybe_raises_SEH_exception_ NTSTATUS NTAPI RtlRunOnceExecuteOnce(_Inout_ PRTL_RUN_ONCE RunOnce, _In_ __inner_callback PRTL_RUN_ONCE_INIT_FN InitFn, _Inout_opt_ PVOID Parameter, _Outptr_opt_result_maybenull_ PVOID *Context)
Definition: runonce.c:121
NTSTATUS NTAPI RtlRunOnceComplete(_Inout_ PRTL_RUN_ONCE RunOnce, _In_ ULONG Flags, _In_opt_ PVOID Context)
Definition: runonce.c:73
_Must_inspect_result_ NTSTATUS NTAPI RtlRunOnceBeginInitialize(_Inout_ PRTL_RUN_ONCE RunOnce, _In_ ULONG Flags, _Outptr_opt_result_maybenull_ PVOID *Context)
Definition: runonce.c:22
#define STATUS_SUCCESS
Definition: shellext.h:65
#define NTAPI
Definition: typedefs.h:36
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
int ret
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
_In_ __inner_callback PRTL_RUN_ONCE_INIT_FN InitFn
Definition: rtlfuncs.h:2533
#define RTL_RUN_ONCE_CHECK_ONLY
#define RTL_RUN_ONCE_ASYNC
_Inout_opt_ PVOID Parameter
Definition: rtltypes.h:323
* PRTL_RUN_ONCE
Definition: rtltypes.h:314
#define RTL_RUN_ONCE_INIT_FAILED
RTL_RUN_ONCE_INIT_FN * PRTL_RUN_ONCE_INIT_FN
Definition: rtltypes.h:325