/* Search @list for element with key @key. The nodes next, cur and prev are returned in @hp Returns true if @value was removed by this call. This function cannot be called from a signal nor with the world stopped. */ gboolean mono_lls_remove (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, MonoLinkedListSetNode *value) { MonoLinkedListSetNode *cur, **prev, *next; while (1) { if (!mono_lls_find (list, hp, value->key)) return FALSE; next = mono_hazard_pointer_get_val (hp, 0); cur = mono_hazard_pointer_get_val (hp, 1); prev = mono_hazard_pointer_get_val (hp, 2); g_assert (cur == value); if (InterlockedCompareExchangePointer ((volatile gpointer*)&cur->next, mask (next, 1), next) != next) continue; /* The second CAS must happen before the first. */ mono_memory_write_barrier (); if (InterlockedCompareExchangePointer ((volatile gpointer*)prev, next, cur) == cur) { /* The CAS must happen before the hazard pointer clear. */ mono_memory_write_barrier (); mono_hazard_pointer_clear (hp, 1); if (list->free_node_func) mono_thread_hazardous_free_or_queue (value, list->free_node_func); } else mono_lls_find (list, hp, value->key); return TRUE; } }
HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo) { HRESULT hres; if (!typelib) { ITypeLib *tl; static const WCHAR vbscript_dll1W[] = {'v','b','s','c','r','i','p','t','.','d','l','l','\\','1',0}; hres = LoadTypeLib(vbscript_dll1W, &tl); if(FAILED(hres)) { ERR("LoadRegTypeLib failed: %08x\n", hres); return hres; } if(InterlockedCompareExchangePointer((void**)&typelib, tl, NULL)) ITypeLib_Release(tl); } if(!typeinfos[tid]) { ITypeInfo *ti; hres = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti); if(FAILED(hres)) { ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids[tid]), hres); return hres; } if(InterlockedCompareExchangePointer((void**)(typeinfos+tid), ti, NULL)) ITypeInfo_Release(ti); } *typeinfo = typeinfos[tid]; return S_OK; }
static HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo) { HRESULT hres; if(!typelib) { ITypeLib *tl; hres = LoadRegTypeLib(&LIBID_MSHTML, 4, 0, LOCALE_SYSTEM_DEFAULT, &tl); if(FAILED(hres)) { ERR("LoadRegTypeLib failed: %08x\n", hres); return hres; } if(InterlockedCompareExchangePointer((void**)&typelib, tl, NULL)) ITypeLib_Release(tl); } if(!typeinfos[tid]) { ITypeInfo *typeinfo; hres = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &typeinfo); if(FAILED(hres)) { ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids[tid]), hres); return hres; } if(InterlockedCompareExchangePointer((void**)(typeinfos+tid), typeinfo, NULL)) ITypeInfo_Release(typeinfo); } *typeinfo = typeinfos[tid]; return S_OK; }
HRESULT get_typeinfo( enum type_id tid, ITypeInfo **ret ) { HRESULT hr; if (!typelib) { ITypeLib *lib; hr = LoadRegTypeLib( &LIBID_NetFwPublicTypeLib, 1, 0, LOCALE_SYSTEM_DEFAULT, &lib ); if (FAILED(hr)) { ERR("LoadRegTypeLib failed: %08x\n", hr); return hr; } if (InterlockedCompareExchangePointer( (void **)&typelib, lib, NULL )) ITypeLib_Release( lib ); } if (!typeinfo[tid]) { ITypeInfo *info; hr = ITypeLib_GetTypeInfoOfGuid( typelib, tid_id[tid], &info ); if (FAILED(hr)) { ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_id[tid]), hr); return hr; } if (InterlockedCompareExchangePointer( (void **)(typeinfo + tid), info, NULL )) ITypeInfo_Release( info ); } *ret = typeinfo[tid]; ITypeInfo_AddRef(typeinfo[tid]); return S_OK; }
HRESULT get_typeinfo(enum tid_t tid, ITypeInfo **typeinfo) { HRESULT hres; if(!typelib) { ITypeLib *tl; hres = LoadRegTypeLib(&LIBID_MSXML2, 3, 0, LOCALE_SYSTEM_DEFAULT, &tl); if(FAILED(hres)) { ERR("LoadRegTypeLib failed: %08x\n", hres); return hres; } if(InterlockedCompareExchangePointer((void**)&typelib, tl, NULL)) ITypeLib_Release(tl); } if(!typeinfos[tid]) { ITypeInfo *ti; hres = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti); if(FAILED(hres)) { ERR("GetTypeInfoOfGuid failed: %08x\n", hres); return hres; } if(InterlockedCompareExchangePointer((void**)(typeinfos+tid), ti, NULL)) ITypeInfo_Release(ti); } *typeinfo = typeinfos[tid]; ITypeInfo_AddRef(typeinfos[tid]); return S_OK; }
int pthread_rwlock_tryrdlock(pthread_rwlock_t *l) { #ifndef PTHREAD_WIN_XP_SYNC /* Get the current state of the lock */ void *state = *(void **) l; if (!state) { /* Unlocked to locked */ if (!InterlockedCompareExchangePointer((PVOID *) l, (void *)0x11, NULL)) return 0; return EBUSY; } /* A single writer exists */ if (state == (void *) 1) return EBUSY; /* Multiple writers exist? */ if ((uintptr_t) state & 14) return EBUSY; if (InterlockedCompareExchangePointer((PVOID *) l, (void *) ((uintptr_t)state + 16), state) == state) return 0; return EBUSY; #else int returnState = EBUSY; WaitForSingleObject(l->mutex,INFINITE); if(l->reader_count >= 0) returnState = 0,++(l->reader_count); ReleaseMutex(l->mutex); return returnState; #endif }
/*++ * ExfReleasePushLockExclusive * @implemented NT5.2 * * The ExfReleasePushLockExclusive routine releases a previously * exclusively acquired PushLock. * * @params PushLock * Pointer to a previously acquired pushlock. * * @return None. * * @remarks Callers of ExReleasePushLockExclusive must be running at IRQL <= APC_LEVEL. * This macro should usually be paired up with KeLeaveCriticalRegion. * *--*/ VOID FASTCALL ExfReleasePushLockExclusive(PEX_PUSH_LOCK PushLock) { EX_PUSH_LOCK NewValue, WakeValue; EX_PUSH_LOCK OldValue = *PushLock; /* Loop until we can change */ for (;;) { /* Sanity checks */ ASSERT(OldValue.Locked); ASSERT(OldValue.Waiting || OldValue.Shared == 0); /* Check if it's waiting and not yet waking */ if ((OldValue.Waiting) && !(OldValue.Waking)) { /* Remove the lock bit, and add the wake bit */ NewValue.Value = (OldValue.Value &~ EX_PUSH_LOCK_LOCK) | EX_PUSH_LOCK_WAKING; /* Sanity check */ ASSERT(NewValue.Waking && !NewValue.Locked); /* Write the New Value. Save our original value for waking */ WakeValue = NewValue; NewValue.Ptr = InterlockedCompareExchangePointer(&PushLock->Ptr, NewValue.Ptr, OldValue.Ptr); /* Check if the value changed behind our back */ if (NewValue.Value == OldValue.Value) { /* Wake the Pushlock */ ExfWakePushLock(PushLock, WakeValue); break; } } else { /* A simple unlock */ NewValue.Value = OldValue.Value &~ EX_PUSH_LOCK_LOCK; /* Sanity check */ ASSERT(NewValue.Waking && !NewValue.Waiting); /* Write the New Value */ NewValue.Ptr = InterlockedCompareExchangePointer(&PushLock->Ptr, NewValue.Ptr, OldValue.Ptr); /* Check if the value changed behind our back */ if (NewValue.Value == OldValue.Value) break; } /* Loop again */ OldValue = NewValue; } }
void mono_lock_free_queue_enqueue (MonoLockFreeQueue *q, MonoLockFreeQueueNode *node) { MonoThreadHazardPointers *hp = mono_hazard_pointer_get (); MonoLockFreeQueueNode *tail; #ifdef QUEUE_DEBUG g_assert (!node->in_queue); node->in_queue = TRUE; mono_memory_write_barrier (); #endif g_assert (node->next == FREE_NEXT); node->next = END_MARKER; for (;;) { MonoLockFreeQueueNode *next; tail = (MonoLockFreeQueueNode *) get_hazardous_pointer ((gpointer volatile*)&q->tail, hp, 0); mono_memory_read_barrier (); /* * We never dereference next so we don't need a * hazardous load. */ next = tail->next; mono_memory_read_barrier (); /* Are tail and next consistent? */ if (tail == q->tail) { g_assert (next != INVALID_NEXT && next != FREE_NEXT); g_assert (next != tail); if (next == END_MARKER) { /* * Here we require that nodes that * have been dequeued don't have * next==END_MARKER. If they did, we * might append to a node that isn't * in the queue anymore here. */ if (InterlockedCompareExchangePointer ((gpointer volatile*)&tail->next, node, END_MARKER) == END_MARKER) break; } else { /* Try to advance tail */ InterlockedCompareExchangePointer ((gpointer volatile*)&q->tail, next, tail); } } mono_memory_write_barrier (); mono_hazard_pointer_clear (hp, 0); } /* Try to advance tail */ InterlockedCompareExchangePointer ((gpointer volatile*)&q->tail, node, tail); mono_memory_write_barrier (); mono_hazard_pointer_clear (hp, 0); }
APR_DECLARE(void *) apr_atomic_casptr(volatile void **mem, void *with, const void *cmp) { #if (defined(_M_IA64) || defined(_M_AMD64)) && !defined(RC_INVOKED) return InterlockedCompareExchangePointer((void* volatile*)mem, with, (void*)cmp); #elif defined(__MINGW32__) return InterlockedCompareExchangePointer((void**)mem, with, (void*)cmp); #else /* Too many VC6 users have stale win32 API files, stub this */ return ((apr_atomic_win32_ptr_ptr_ptr_fn)InterlockedCompareExchange)(mem, with, cmp); #endif }
static gpointer alloc_from_active_or_partial (MonoLockFreeAllocator *heap) { Descriptor *desc; Anchor old_anchor, new_anchor; gpointer addr; retry: desc = heap->active; if (desc) { if (InterlockedCompareExchangePointer ((gpointer * volatile)&heap->active, NULL, desc) != desc) goto retry; } else { desc = heap_get_partial (heap); if (!desc) return NULL; } /* Now we own the desc. */ do { unsigned int next; new_anchor = old_anchor = (Anchor)*(volatile gint32*)&desc->anchor.value; if (old_anchor.data.state == STATE_EMPTY) { /* We must free it because we own it. */ desc_retire (desc); goto retry; } g_assert (old_anchor.data.state == STATE_PARTIAL); g_assert (old_anchor.data.count > 0); addr = (char*)desc->sb + old_anchor.data.avail * desc->slot_size; mono_memory_read_barrier (); next = *(unsigned int*)addr; g_assert (next < SB_USABLE_SIZE / desc->slot_size); new_anchor.data.avail = next; --new_anchor.data.count; if (new_anchor.data.count == 0) new_anchor.data.state = STATE_FULL; } while (!set_anchor (desc, old_anchor, new_anchor)); /* If the desc is partial we have to give it back. */ if (new_anchor.data.state == STATE_PARTIAL) { if (InterlockedCompareExchangePointer ((gpointer * volatile)&heap->active, desc, NULL) != NULL) heap_put_partial (desc); } return addr; }
NTKERNELAPI VOID DECLSPEC_NOINLINE FASTCALL ExfReleasePushLockExclusive ( __inout PEX_PUSH_LOCK PushLock ) /*++ Routine Description: Release a push lock that was acquired exclusive Arguments: PushLock - Push lock to be released Return Value: None --*/ { EX_PUSH_LOCK OldValue, NewValue, TopValue; OldValue = ReadForWriteAccess (PushLock); while (1) { ASSERT (OldValue.Locked); ASSERT (OldValue.Waiting || OldValue.Shared == 0); if (OldValue.Waiting && !OldValue.Waking) { NewValue.Value = OldValue.Value - EX_PUSH_LOCK_LOCK + EX_PUSH_LOCK_WAKING; ASSERT (NewValue.Waking && !NewValue.Locked); TopValue = NewValue; if ((NewValue.Ptr = InterlockedCompareExchangePointer (&PushLock->Ptr, NewValue.Ptr, OldValue.Ptr)) == OldValue.Ptr) { ExfWakePushLock (PushLock, TopValue); break; } } else { NewValue.Value = OldValue.Value - EX_PUSH_LOCK_LOCK; ASSERT (NewValue.Waking || !NewValue.Waiting); if ((NewValue.Ptr = InterlockedCompareExchangePointer (&PushLock->Ptr, NewValue.Ptr, OldValue.Ptr)) == OldValue.Ptr) { break; } } OldValue = NewValue; } }
void mono_lock_free_free (gpointer ptr, size_t block_size) { Anchor old_anchor, new_anchor; Descriptor *desc; gpointer sb; MonoLockFreeAllocator *heap = NULL; desc = *(Descriptor**) sb_header_for_addr (ptr, block_size); g_assert (block_size == desc->block_size); sb = desc->sb; do { new_anchor = old_anchor = *(volatile Anchor*)&desc->anchor.value; *(unsigned int*)ptr = old_anchor.data.avail; new_anchor.data.avail = ((char*)ptr - (char*)sb) / desc->slot_size; g_assert (new_anchor.data.avail < LOCK_FREE_ALLOC_SB_USABLE_SIZE (block_size) / desc->slot_size); if (old_anchor.data.state == STATE_FULL) new_anchor.data.state = STATE_PARTIAL; if (++new_anchor.data.count == desc->max_count) { heap = desc->heap; new_anchor.data.state = STATE_EMPTY; } } while (!set_anchor (desc, old_anchor, new_anchor)); if (new_anchor.data.state == STATE_EMPTY) { g_assert (old_anchor.data.state != STATE_EMPTY); if (InterlockedCompareExchangePointer ((gpointer * volatile)&heap->active, NULL, desc) == desc) { /* We own it, so we free it. */ desc_retire (desc); } else { /* * Somebody else must free it, so we do some * freeing for others. */ list_remove_empty_desc (heap->sc); } } else if (old_anchor.data.state == STATE_FULL) { /* * Nobody owned it, now we do, so we need to give it * back. */ g_assert (new_anchor.data.state == STATE_PARTIAL); if (InterlockedCompareExchangePointer ((gpointer * volatile)&desc->heap->active, desc, NULL) != NULL) heap_put_partial (desc); } }
int __cdecl main(int argc, char *argv[]) { long StartValue = 5; long NewValue = 10; PVOID ReturnValue = NULL; /* * Initialize the PAL and return FAILURE if this fails */ if(0 != (PAL_Initialize(argc, argv))) { return FAIL; } ReturnValue = InterlockedCompareExchangePointer((PVOID)&StartValue, (PVOID)NewValue, (PVOID)StartValue); /* StartValue and NewValue should be equal now */ if(StartValue != NewValue) { Fail("ERROR: These values should be equal after the exchange. " "They should both be %d, however the value that should have " "been exchanged is %d.\n",NewValue,StartValue); } /* Returnvalue should have been set to what 'StartValue' was (5 in this case) */ if((int)(size_t)ReturnValue != 5) { Fail("ERROR: The return value should be the value of the " "variable before the exchange took place, which was 5. " "But, the return value was %d.\n",ReturnValue); } /* This is a mismatch, so no exchange should happen */ InterlockedCompareExchangePointer((PVOID)&StartValue, ReturnValue, ReturnValue); if(StartValue != NewValue) { Fail("ERROR: The compare should have failed and no exchange should " "have been made, but it seems the exchange still happened.\n"); } PAL_Terminate(); return PASS; }
/* * ptw32_mcs_flag_set -- wait for notification from another. * * Store an event handle in the flag and wait on it if the flag has not been * set, and proceed without creating an event otherwise. */ static inline void ptw32_mcs_flag_wait(PVOID volatile *flag) { if (0 == InterlockedCompareExchangePointer(flag, 0, 0)) { /* MBR fence */ /* the flag is not set. create event. */ HANDLE e = CreateEvent(NULL, FALSE, FALSE, NULL); if (0 == InterlockedCompareExchangePointer(flag, (void *) e, (void *) 0)) { /* stored handle in the flag. wait on it now. */ WaitForSingleObject(e, INFINITE); } CloseHandle(e); } }
static void pushJobs(JobDecl* pJobDcls, int numJobs, Counter** ppCounter, int threadMask) { //alloc counter if (ppCounter != NULL) { allocCounter(ppCounter); (*ppCounter)->counter = numJobs; } for (int i = 0; i < numJobs; ++i) { Job* pJob; Job* pNewHead; for (;;) { pNewHead = g_pFreeJob; if (InterlockedCompareExchangePointer(&g_pFreeJob, pNewHead->pNextJob, pNewHead) == pNewHead) { pNewHead->pNextJob = NULL; break; } } for (;;) { pJob = g_pJobQueueHead; if (InterlockedCompareExchangePointer(&g_pJobQueueHead, pNewHead, pJob) == pJob) { break; } } pJob->fpFunction = pJobDcls[i].fpFunction; pJob->pParams = pJobDcls[i].pParams; pJob->pName = pJobDcls[i].pName; pJob->threadId = threadMask; pJob->pCounter = ppCounter == 0 ? 0 : *ppCounter; MemoryBarrier(); pJob->pNextJob = pNewHead; } #ifdef DEBUG_OUTPUT fprintf(g_pDebugLog, "%lld \t %i new jobs added (%s %x) \n\t\t new job head: %i\n", time(NULL), numJobs, pJobDcls->pName, threadMask, g_pJobQueueHead - g_jobs); #endif }
static Descriptor* desc_alloc (void) { MonoThreadHazardPointers *hp = mono_hazard_pointer_get (); Descriptor *desc; for (;;) { gboolean success; desc = (Descriptor *) get_hazardous_pointer ((gpointer * volatile)&desc_avail, hp, 1); if (desc) { Descriptor *next = desc->next; success = (InterlockedCompareExchangePointer ((gpointer * volatile)&desc_avail, next, desc) == desc); } else { size_t desc_size = sizeof (Descriptor); Descriptor *d; int i; desc = (Descriptor *) mono_valloc (0, desc_size * NUM_DESC_BATCH, prot_flags_for_activate (TRUE)); /* Organize into linked list. */ d = desc; for (i = 0; i < NUM_DESC_BATCH; ++i) { Descriptor *next = (i == (NUM_DESC_BATCH - 1)) ? NULL : (Descriptor*)((char*)desc + ((i + 1) * desc_size)); d->next = next; mono_lock_free_queue_node_init (&d->node, TRUE); d = next; } mono_memory_write_barrier (); success = (InterlockedCompareExchangePointer ((gpointer * volatile)&desc_avail, desc->next, NULL) == NULL); if (!success) mono_vfree (desc, desc_size * NUM_DESC_BATCH); } mono_hazard_pointer_clear (hp, 1); if (success) break; } g_assert (!desc->in_use); desc->in_use = TRUE; return desc; }
HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo) { HRESULT hres; if (!typelib) hres = load_typelib(); if (!typelib) return hres; if(!typeinfos[tid]) { ITypeInfo *ti; hres = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti); if(FAILED(hres)) { ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids[tid]), hres); return hres; } if(InterlockedCompareExchangePointer((void**)(typeinfos+tid), ti, NULL)) ITypeInfo_Release(ti); } *typeinfo = typeinfos[tid]; ITypeInfo_AddRef(*typeinfo); return S_OK; }
PWINECRYPT_CERTSTORE CRYPT_RootOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags) { TRACE("(%ld, %08x)\n", hCryptProv, dwFlags); if (dwFlags & CERT_STORE_DELETE_FLAG) { WARN("root store can't be deleted\n"); SetLastError(ERROR_ACCESS_DENIED); return NULL; } switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK) { case CERT_SYSTEM_STORE_LOCAL_MACHINE: case CERT_SYSTEM_STORE_CURRENT_USER: break; default: TRACE("location %08x unsupported\n", dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK); SetLastError(E_INVALIDARG); return NULL; } if (!CRYPT_rootStore) { HCERTSTORE root = CRYPT_RootOpenStoreFromKnownLocations(); InterlockedCompareExchangePointer((PVOID *)&CRYPT_rootStore, root, NULL); if (CRYPT_rootStore != root) CertCloseStore(root, 0); } CertDuplicateStore(CRYPT_rootStore); return CRYPT_rootStore; }
static inline int _InitWaitCriticalSection(RTL_CRITICAL_SECTION *prc) { int r = 0; HANDLE evt; LONG LockCount = prc->LockCount; r = 0; if (!prc->OwningThread || !prc->RecursionCount || (LockCount & 1)) { /* not locked (anymore), caller should redo trylock sequence: */ return EAGAIN; } else { _ReadWriteBarrier(); if( LockCount != InterlockedCompareExchange(&prc->LockCount, LockCount+LockDelta, LockCount) ) { /* recheck here too: */ return EAGAIN; } } if ( !prc->LockSemaphore) { if (!(evt = CreateEvent(NULL,FALSE,FALSE,NULL)) ) { InterlockedExchangeAdd(&prc->LockCount, -LockDelta); return ENOMEM; } if(InterlockedCompareExchangePointer(&prc->LockSemaphore,evt,NULL)) { /* someone sneaked in between, keep the original: */ CloseHandle(evt); } } return r; }
static HCRYPTPROV nr_CryptProvider(void) { BOOL rv; HCRYPTPROV cryptprovider = 0; if (nr_cryptprovider != 0) return nr_cryptprovider; rv = CryptAcquireContext(&cryptprovider, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, 0); if (GetLastError() == NTE_BAD_KEYSET) { if(!rv) rv = CryptAcquireContext(&cryptprovider, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET); } if (rv && InterlockedCompareExchangePointer((PVOID *) &nr_cryptprovider, (PVOID) cryptprovider, 0) != 0) { CryptReleaseContext(cryptprovider, 0); cryptprovider = nr_cryptprovider; } return cryptprovider; }
static NTSTATUS InitPool( VOID ) { NTSTATUS status = STATUS_SUCCESS; PLW_THREAD_POOL pNewPool = NULL; if (!gSvcmState.pPool) { status = LwRtlCreateThreadPool(&pNewPool, NULL); GCOS(status); if (InterlockedCompareExchangePointer( OUT_PPVOID(&gSvcmState.pPool), pNewPool, NULL) != NULL) { LwRtlFreeThreadPool(&pNewPool); } } cleanup: return status; }
static HRESULT WINAPI BitmapImpl_SetPalette(IWICBitmap *iface, IWICPalette *pIPalette) { BitmapImpl *This = impl_from_IWICBitmap(iface); HRESULT hr; TRACE("(%p,%p)\n", iface, pIPalette); if (!This->palette) { IWICPalette *new_palette; hr = PaletteImpl_Create(&new_palette); if (FAILED(hr)) return hr; if (InterlockedCompareExchangePointer((void**)&This->palette, new_palette, NULL)) { /* someone beat us to it */ IWICPalette_Release(new_palette); } } hr = IWICPalette_InitializeFromPalette(This->palette, pIPalette); if (SUCCEEDED(hr)) This->palette_set = 1; return S_OK; }
static NOINLINE void uv__once_inner(uv_once_t* guard, void (*callback)(void)) { DWORD result; HANDLE existing_event, created_event; created_event = CreateEvent(NULL, 1, 0, NULL); if (created_event == 0) { /* Could fail in a low-memory situation? */ uv_fatal_error(GetLastError(), "CreateEvent"); } existing_event = InterlockedCompareExchangePointer(&guard->event, created_event, NULL); if (existing_event == NULL) { /* We won the race */ callback(); result = SetEvent(created_event); assert(result); guard->ran = 1; } else { /* We lost the race. Destroy the event we created and wait for the */ /* existing one todv become signaled. */ CloseHandle(created_event); result = WaitForSingleObject(existing_event, INFINITE); assert(result == WAIT_OBJECT_0); } }
/****************************************** * IWICStream_InitializeFromMemory * * Initializes the internal IStream object to retrieve its data from a memory chunk. * * PARAMS * pbBuffer [I] pointer to the memory chunk * cbBufferSize [I] number of bytes to use from the memory chunk * * RETURNS * SUCCESS: S_OK * FAILURE: E_INVALIDARG, if pbBuffer is NULL * E_OUTOFMEMORY, if we run out of memory * WINCODEC_ERR_WRONGSTATE, if the IStream object has already been initialized before * */ static HRESULT WINAPI IWICStreamImpl_InitializeFromMemory(IWICStream *iface, BYTE *pbBuffer, DWORD cbBufferSize) { IWICStreamImpl *This = impl_from_IWICStream(iface); StreamOnMemory *pObject; TRACE("(%p,%p)\n", iface, pbBuffer); if (!pbBuffer) return E_INVALIDARG; if (This->pStream) return WINCODEC_ERR_WRONGSTATE; pObject = HeapAlloc(GetProcessHeap(), 0, sizeof(StreamOnMemory)); if (!pObject) return E_OUTOFMEMORY; pObject->IStream_iface.lpVtbl = &StreamOnMemory_Vtbl; pObject->ref = 1; pObject->pbMemory = pbBuffer; pObject->dwMemsize = cbBufferSize; pObject->dwCurPos = 0; InitializeCriticalSection(&pObject->lock); pObject->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": StreamOnMemory.lock"); if (InterlockedCompareExchangePointer((void**)&This->pStream, pObject, NULL)) { /* Some other thread set the stream first. */ IStream_Release(&pObject->IStream_iface); return WINCODEC_ERR_WRONGSTATE; } return S_OK; }
const char * __thiscall MSVCRT_type_info_name(type_info * _this) { if (!_this->name) { /* Create and set the demangled name */ /* Note: mangled name in type_info struct always starts with a '.', while * it isn't valid for mangled name. * Is this '.' really part of the mangled name, or has it some other meaning ? */ char* name = __unDName(0, _this->mangled + 1, 0, MSVCRT_malloc, MSVCRT_free, UNDNAME_NO_ARGUMENTS | UNDNAME_32_BIT_DECODE); if (name) { unsigned int len = strlen(name); /* It seems _unDName may leave blanks at the end of the demangled name */ while (len && name[--len] == ' ') name[len] = '\0'; if (InterlockedCompareExchangePointer((void**)&_this->name, name, NULL)) { /* Another thread set this member since we checked above - use it */ MSVCRT_free(name); } } } TRACE("(%p) returning %s\n", _this, _this->name); return _this->name; }
static HRESULT WINAPI IWICStreamImpl_InitializeFromFilename(IWICStream *iface, LPCWSTR wzFileName, DWORD dwDesiredAccess) { IWICStreamImpl *This = impl_from_IWICStream(iface); HRESULT hr; DWORD dwMode; IStream *stream; TRACE("(%p, %s, %u)\n", iface, debugstr_w(wzFileName), dwDesiredAccess); if (This->pStream) return WINCODEC_ERR_WRONGSTATE; if(dwDesiredAccess & GENERIC_WRITE) dwMode = STGM_SHARE_DENY_WRITE | STGM_WRITE | STGM_CREATE; else if(dwDesiredAccess & GENERIC_READ) dwMode = STGM_SHARE_DENY_WRITE | STGM_READ | STGM_FAILIFTHERE; else return E_INVALIDARG; hr = SHCreateStreamOnFileW(wzFileName, dwMode, &stream); if (SUCCEEDED(hr)) { if (InterlockedCompareExchangePointer((void**)&This->pStream, stream, NULL)) { /* Some other thread set the stream first. */ IStream_Release(stream); hr = WINCODEC_ERR_WRONGSTATE; } } return hr; }
static HRESULT WINAPI IWICStreamImpl_InitializeFromIStreamRegion(IWICStream *iface, IStream *pIStream, ULARGE_INTEGER ulOffset, ULARGE_INTEGER ulMaxSize) { IWICStreamImpl *This = impl_from_IWICStream(iface); StreamOnStreamRange *pObject; TRACE("(%p,%p)\n", iface, pIStream); if (!pIStream) return E_INVALIDARG; if (This->pStream) return WINCODEC_ERR_WRONGSTATE; pObject = HeapAlloc(GetProcessHeap(), 0, sizeof(StreamOnStreamRange)); if (!pObject) return E_OUTOFMEMORY; pObject->IStream_iface.lpVtbl = &StreamOnStreamRange_Vtbl; pObject->ref = 1; IStream_AddRef(pIStream); pObject->stream = pIStream; pObject->pos.QuadPart = 0; pObject->offset = ulOffset; pObject->max_size = ulMaxSize; InitializeCriticalSection(&pObject->lock); pObject->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": StreamOnStreamRange.lock"); if (InterlockedCompareExchangePointer((void**)&This->pStream, pObject, NULL)) { /* Some other thread set the stream first. */ IStream_Release(&pObject->IStream_iface); return WINCODEC_ERR_WRONGSTATE; } return S_OK; }
void ssh_mutex_lock(SSH_MUTEX *mutex) { void *rc; CRITICAL_SECTION *mutex_tmp = NULL; if (*mutex == NULL) { mutex_tmp = malloc(sizeof(CRITICAL_SECTION)); if (mutex_tmp == NULL) { exit(ENOMEM); } InitializeCriticalSection(mutex_tmp); rc = InterlockedCompareExchangePointer((PVOID*)mutex, (PVOID)mutex_tmp, NULL); if (rc != NULL) { DeleteCriticalSection(mutex_tmp); free(mutex_tmp); exit(ENOMEM); } } EnterCriticalSection(*mutex); }
/*++ * @name ExfTryToWakePushLock * @implemented NT5.2 * * The ExfTryToWakePushLock attemps to wake a waiting pushlock. * * @param PushLock * Pointer to a PushLock which is in the wait state. * * @return None. * * @remarks The pushlock must be in a wait state and must not be already waking. * *--*/ VOID FASTCALL ExfTryToWakePushLock(PEX_PUSH_LOCK PushLock) { EX_PUSH_LOCK OldValue = *PushLock, NewValue; /* * If the Pushlock is not waiting on anything, or if it's already waking up * and locked, don't do anything */ if ((OldValue.Waking) || (OldValue.Locked) || !(OldValue.Waiting)) return; /* Make it Waking */ NewValue = OldValue; NewValue.Waking = TRUE; /* Write the New Value */ if (InterlockedCompareExchangePointer(&PushLock->Ptr, NewValue.Ptr, OldValue.Ptr) == OldValue.Ptr) { /* Wake the Pushlock */ ExfWakePushLock(PushLock, NewValue); } }
/*++ * @name ExBlockPushLock * * The ExBlockPushLock routine blocks a pushlock. * * @param PushLock * Pointer to a pushlock whose waiter list needs to be optimized. * * @param WaitBlock * Pointer to the pushlock's wait block. * * @return None. * * @remarks None. * *--*/ VOID FASTCALL ExBlockPushLock(PEX_PUSH_LOCK PushLock, PVOID pWaitBlock) { PEX_PUSH_LOCK_WAIT_BLOCK WaitBlock = pWaitBlock; EX_PUSH_LOCK NewValue, OldValue; /* Detect invalid wait block alignment */ ASSERT(((ULONG_PTR)pWaitBlock & 0xF) == 0); /* Set the waiting bit */ WaitBlock->Flags = EX_PUSH_LOCK_FLAGS_WAIT; /* Get the old value */ OldValue = *PushLock; /* Start block loop */ for (;;) { /* Link the wait blocks */ WaitBlock->Next = OldValue.Ptr; /* Set the new wait block value */ NewValue.Ptr = InterlockedCompareExchangePointer(&PushLock->Ptr, WaitBlock, OldValue.Ptr); if (OldValue.Ptr == NewValue.Ptr) break; /* Try again with the new value */ OldValue = NewValue; } }