ReactOS 0.4.15-dev-6068-g8061a6f
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 once->Ptr = NULL;
14}
15
16/******************************************************************
17 * RtlRunOnceBeginInitialize (NTDLL.@)
18 */
20{
22 {
23 ULONG_PTR val = (ULONG_PTR)once->Ptr;
24
26 if ((val & 3) != 2) return STATUS_UNSUCCESSFUL;
27 if (context) *context = (void *)(val & ~3);
28 return STATUS_SUCCESS;
29 }
30
31 for (;;)
32 {
33 ULONG_PTR next, val = (ULONG_PTR)once->Ptr;
34
35 switch (val & 3)
36 {
37 case 0: /* first time */
38 if (!interlocked_cmpxchg_ptr( &once->Ptr,
39 (flags & RTL_RUN_ONCE_ASYNC) ? (void *)3 : (void *)1, 0 ))
40 return STATUS_PENDING;
41 break;
42
43 case 1: /* in progress, wait */
45 next = val & ~3;
46 if (interlocked_cmpxchg_ptr( &once->Ptr, (void *)((ULONG_PTR)&next | 1),
47 (void *)val ) == (void *)val)
49 break;
50
51 case 2: /* done */
52 if (context) *context = (void *)(val & ~3);
53 return STATUS_SUCCESS;
54
55 case 3: /* in progress, async */
57 return STATUS_PENDING;
58 }
59 }
60}
61
62/******************************************************************
63 * RtlRunOnceComplete (NTDLL.@)
64 */
66{
68
70 {
73 }
74 else context = (void *)((ULONG_PTR)context | 2);
75
76 for (;;)
77 {
78 ULONG_PTR val = (ULONG_PTR)once->Ptr;
79
80 switch (val & 3)
81 {
82 case 1: /* in progress */
83 if (interlocked_cmpxchg_ptr( &once->Ptr, context, (void *)val ) != (void *)val) break;
84 val &= ~3;
85 while (val)
86 {
88 NtReleaseKeyedEvent( 0, (void *)val, FALSE, NULL );
89 val = next;
90 }
91 return STATUS_SUCCESS;
92
93 case 3: /* in progress, async */
95 if (interlocked_cmpxchg_ptr( &once->Ptr, context, (void *)val ) != (void *)val) break;
96 return STATUS_SUCCESS;
97
98 default:
100 }
101 }
102}
103
104/******************************************************************
105 * RtlRunOnceExecuteOnce (NTDLL.@)
106 */
108 void *param, void **context )
109{
111
112 if (ret != STATUS_PENDING) return ret;
113
114 if (!func( once, param, context ))
115 {
117 return STATUS_UNSUCCESSFUL;
118 }
119
120 return RtlRunOnceComplete( once, 0, context ? *context : NULL );
121}
#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
GLenum func
Definition: glext.h:6028
GLbitfield flags
Definition: glext.h:7161
GLuint GLfloat * val
Definition: glext.h:7180
GLfloat param
Definition: glext.h:5796
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 STATUS_PENDING
Definition: ntstatus.h:82
static unsigned __int64 next
Definition: rand_nt.c:6
#define interlocked_cmpxchg_ptr
Definition: port.h:344
DWORD WINAPI RtlRunOnceComplete(RTL_RUN_ONCE *once, ULONG flags, void *context)
Definition: runonce.c:65
DWORD WINAPI RtlRunOnceBeginInitialize(RTL_RUN_ONCE *once, ULONG flags, void **context)
Definition: runonce.c:19
DWORD WINAPI RtlRunOnceExecuteOnce(RTL_RUN_ONCE *once, PRTL_RUN_ONCE_INIT_FN func, void *param, void **context)
Definition: runonce.c:107
void WINAPI RtlRunOnceInitialize(RTL_RUN_ONCE *once)
Definition: runonce.c:11
#define STATUS_SUCCESS
Definition: shellext.h:65
Definition: http.c:7252
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
#define WINAPI
Definition: msvc.h:6
RTL_RUN_ONCE_INIT_FN * PRTL_RUN_ONCE_INIT_FN
Definition: winnt_old.h:2788
#define RTL_RUN_ONCE_CHECK_ONLY
#define RTL_RUN_ONCE_ASYNC
#define RTL_RUN_ONCE_INIT_FAILED