Wrap platform "thread-safe run once" APIs.

This commit is contained in:
Ben Noordhuis 2011-12-20 16:55:53 +01:00
parent a993329c02
commit 69ce0145f6
5 changed files with 24 additions and 18 deletions

View File

@ -44,6 +44,9 @@ typedef struct {
typedef int uv_file;
#define UV_ONCE_INIT PTHREAD_ONCE_INIT
typedef pthread_once_t uv_once_t;
typedef pthread_t uv_thread_t;
typedef pthread_mutex_t uv_mutex_t;
typedef pthread_rwlock_t uv_rwlock_t;

View File

@ -152,6 +152,16 @@ typedef union {
} fallback_;
} uv_rwlock_t;
#define UV_ONCE_INIT { 0, NULL, NULL }
typedef struct uv_once_s {
unsigned char ran;
/* The actual event handle must be aligned to sizeof(HANDLE), so in */
/* practice it might overlap padding a little. */
HANDLE event;
HANDLE padding;
} uv_once_t;
/* Platform-specific definitions for uv_dlopen support. */
typedef HMODULE uv_lib_t;
#define UV_DYNAMIC FAR WINAPI

View File

@ -1339,6 +1339,12 @@ UV_EXTERN void uv_rwlock_wrlock(uv_rwlock_t* rwlock);
UV_EXTERN int uv_rwlock_trywrlock(uv_rwlock_t* rwlock);
UV_EXTERN void uv_rwlock_wrunlock(uv_rwlock_t* rwlock);
/* Runs a function once and only once. Concurrent calls to uv_once() with the
* same guard will block all callers except one (it's unspecified which one).
* The guard should be initialized statically with the UV_ONCE_INIT macro.
*/
UV_EXTERN void uv_once(uv_once_t* guard, void (*callback)(void));
UV_EXTERN int uv_thread_create(uv_thread_t *tid,
void (*entry)(void *arg), void *arg);
UV_EXTERN int uv_thread_join(uv_thread_t *tid);

View File

@ -151,3 +151,8 @@ int uv_rwlock_trywrlock(uv_rwlock_t* rwlock) {
void uv_rwlock_wrunlock(uv_rwlock_t* rwlock) {
CHECK(pthread_rwlock_unlock(rwlock));
}
void uv_once(uv_once_t* guard, void (*callback)(void)) {
CHECK(pthread_once(guard, callback));
}

View File

@ -343,22 +343,4 @@ extern int uv_allow_ipv6;
extern struct sockaddr_in uv_addr_ip4_any_;
extern struct sockaddr_in6 uv_addr_ip6_any_;
/*
* Threads and synchronization
*/
typedef struct uv_once_s {
unsigned char ran;
/* The actual event handle must be aligned to sizeof(HANDLE), so in */
/* practice it might overlap padding a little. */
HANDLE event;
HANDLE padding;
} uv_once_t;
#define UV_ONCE_INIT \
{ 0, NULL, NULL }
void uv_once(uv_once_t* guard, void (*callback)(void));
#endif /* UV_WIN_INTERNAL_H_ */