ReactOS  0.4.15-dev-1184-g23e04ae
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:
99  return STATUS_UNSUCCESSFUL;
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 }
GLenum func
Definition: glext.h:6028
NTSYSAPI NTSTATUS WINAPI NtWaitForKeyedEvent(HANDLE, const void *, BOOLEAN, const LARGE_INTEGER *)
Definition: http.c:7094
void WINAPI RtlRunOnceInitialize(RTL_RUN_ONCE *once)
Definition: runonce.c:11
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define RTL_RUN_ONCE_CHECK_ONLY
void * interlocked_cmpxchg_ptr(void **dest, void *xchg, void *compare)
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define RTL_RUN_ONCE_INIT_FAILED
#define FALSE
Definition: types.h:117
DWORD WINAPI RtlRunOnceComplete(RTL_RUN_ONCE *once, ULONG flags, void *context)
Definition: runonce.c:65
NTSYSAPI NTSTATUS WINAPI NtReleaseKeyedEvent(HANDLE, const void *, BOOLEAN, const LARGE_INTEGER *)
smooth NULL
Definition: ftsmooth.c:416
switch(r->id)
Definition: btrfs.c:2980
GLuint GLfloat * val
Definition: glext.h:7180
DWORD WINAPI RtlRunOnceBeginInitialize(RTL_RUN_ONCE *once, ULONG flags, void **context)
Definition: runonce.c:19
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define STATUS_PENDING
Definition: ntstatus.h:82
GLfloat param
Definition: glext.h:5796
#define WINAPI
Definition: msvc.h:6
RTL_RUN_ONCE_INIT_FN * PRTL_RUN_ONCE_INIT_FN
Definition: winnt_old.h:2608
DWORD WINAPI RtlRunOnceExecuteOnce(RTL_RUN_ONCE *once, PRTL_RUN_ONCE_INIT_FN func, void *param, void **context)
Definition: runonce.c:107
unsigned long DWORD
Definition: ntddk_ex.h:95
GLbitfield flags
Definition: glext.h:7161
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
int ret
static unsigned __int64 next
Definition: rand_nt.c:6
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
return STATUS_SUCCESS
Definition: btrfs.c:3014
#define RTL_RUN_ONCE_ASYNC