gdi32: Fix leak in GdiDeleteSpoolFileHandle.
[wine.git] / dlls / msvcp140_atomic_wait / main.c
blobb7aa30200ff847b79cfd7ca9318de0d9601c259d
1 /*
2 * Copyright 2022 Daniel Lehman
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include <stdarg.h>
20 #include "windef.h"
21 #include "winbase.h"
22 #include "wine/debug.h"
23 #include "wine/list.h"
25 WINE_DEFAULT_DEBUG_CHANNEL(msvcp);
27 extern unsigned int __cdecl _Thrd_hardware_concurrency(void);
29 unsigned int __stdcall __std_parallel_algorithms_hw_threads(void)
31 TRACE("()\n");
32 return _Thrd_hardware_concurrency();
35 void __stdcall __std_bulk_submit_threadpool_work(PTP_WORK work, size_t count)
37 TRACE("(%p %Iu)\n", work, count);
38 while (count--)
39 SubmitThreadpoolWork(work);
42 void __stdcall __std_close_threadpool_work(PTP_WORK work)
44 TRACE("(%p)\n", work);
45 return CloseThreadpoolWork(work);
48 PTP_WORK __stdcall __std_create_threadpool_work(PTP_WORK_CALLBACK callback, void *context,
49 PTP_CALLBACK_ENVIRON environ)
51 TRACE("(%p %p %p)\n", callback, context, environ);
52 return CreateThreadpoolWork(callback, context, environ);
55 void __stdcall __std_submit_threadpool_work(PTP_WORK work)
57 TRACE("(%p)\n", work);
58 return SubmitThreadpoolWork(work);
61 void __stdcall __std_wait_for_threadpool_work_callbacks(PTP_WORK work, BOOL cancel)
63 TRACE("(%p %d)\n", work, cancel);
64 return WaitForThreadpoolWorkCallbacks(work, cancel);
67 void __stdcall __std_atomic_notify_one_direct(void *addr)
69 TRACE("(%p)\n", addr);
70 WakeByAddressSingle(addr);
73 void __stdcall __std_atomic_notify_all_direct(void *addr)
75 TRACE("(%p)\n", addr);
76 WakeByAddressAll(addr);
79 BOOL __stdcall __std_atomic_wait_direct(volatile void *addr, void *cmp,
80 SIZE_T size, DWORD timeout)
82 TRACE("(%p %p %Id %ld)\n", addr, cmp, size, timeout);
83 return WaitOnAddress(addr, cmp, size, timeout);
86 typedef struct
88 SRWLOCK srwlock;
89 } shared_mutex;
91 struct shared_mutex_elem
93 struct list entry;
94 int ref;
95 void *ptr;
96 shared_mutex mutex;
99 static CRITICAL_SECTION shared_mutex_cs;
100 static CRITICAL_SECTION_DEBUG shared_mutex_cs_debug =
102 0, 0, &shared_mutex_cs,
103 { &shared_mutex_cs_debug.ProcessLocksList, &shared_mutex_cs_debug.ProcessLocksList },
104 0, 0, { (DWORD_PTR)(__FILE__ ": shared_mutex_cs") }
106 static CRITICAL_SECTION shared_mutex_cs = { &shared_mutex_cs_debug, -1, 0, 0, 0, 0 };
107 static struct list shared_mutex_list = LIST_INIT(shared_mutex_list);
109 /* shared_mutex_cs must be held by caller */
110 static struct shared_mutex_elem* find_shared_mutex(void *ptr)
112 struct shared_mutex_elem *sme;
114 LIST_FOR_EACH_ENTRY(sme, &shared_mutex_list, struct shared_mutex_elem, entry)
116 if (sme->ptr == ptr)
117 return sme;
119 return NULL;
122 shared_mutex* __stdcall __std_acquire_shared_mutex_for_instance(void *ptr)
124 struct shared_mutex_elem *sme;
126 TRACE("(%p)\n", ptr);
128 EnterCriticalSection(&shared_mutex_cs);
129 sme = find_shared_mutex(ptr);
130 if (sme)
132 sme->ref++;
133 LeaveCriticalSection(&shared_mutex_cs);
134 return &sme->mutex;
137 sme = malloc(sizeof(*sme));
138 sme->ref = 1;
139 sme->ptr = ptr;
140 InitializeSRWLock(&sme->mutex.srwlock);
141 list_add_head(&shared_mutex_list, &sme->entry);
142 LeaveCriticalSection(&shared_mutex_cs);
143 return &sme->mutex;
146 void __stdcall __std_release_shared_mutex_for_instance(void *ptr)
148 struct shared_mutex_elem *sme;
150 TRACE("(%p)\n", ptr);
152 EnterCriticalSection(&shared_mutex_cs);
153 sme = find_shared_mutex(ptr);
154 if (!sme)
156 LeaveCriticalSection(&shared_mutex_cs);
157 return;
160 sme->ref--;
161 if (!sme->ref)
163 list_remove(&sme->entry);
164 free(sme);
166 LeaveCriticalSection(&shared_mutex_cs);