I got bored at general lack of interest over broken mouse capturing implementation and decided to do something different. Changelog: Implemented pthread_rwlock stubs. Index: wine/scheduler/pthread.c =================================================================== RCS file: /home/wine/wine/scheduler/pthread.c,v retrieving revision 1.18 diff -u -r1.18 pthread.c --- wine/scheduler/pthread.c 2001/11/19 02:30:13 1.18 +++ wine/scheduler/pthread.c 2001/12/09 15:13:24 @@ -18,6 +18,7 @@ #include "winbase.h" #include "thread.h" +#include "ntddk.h" static int init_done; @@ -72,17 +73,27 @@ extern pid_t LIBC_FORK(void); #define LIBC_SIGACTION __sigaction +extern int LIBC_SIGACTION(int signum, + const struct sigaction *act, + struct sigaction *oldact); /* NOTE: This is a truly extremely incredibly ugly hack! * But it does seem to work... */ /* assume that pthread_mutex_t has room for at least one pointer, * and hope that the users of pthread_mutex_t considers it opaque - * (never checks what's in it) */ + * (never checks what's in it) + * also: assume that static initializer sets pointer to NULL + */ typedef struct { CRITICAL_SECTION *critsect; } *wine_mutex; +/* see wine_mutex above for comments */ +typedef struct { + RTL_RWLOCK *lock; +} *wine_rwlock; + typedef struct _wine_cleanup { void (*routine)(void *); void *arg; @@ -403,53 +414,91 @@ #if (__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 2) /***** READ-WRITE LOCKS *****/ -/* not implemented right now */ +static void rwlock_real_init(pthread_rwlock_t *rwlock) +{ + RTL_RWLOCK *lock = HeapAlloc(GetProcessHeap(), 0, sizeof(RTL_RWLOCK)); + RtlInitializeResource(lock); + + if (InterlockedCompareExchangePointer((void**)&(((wine_rwlock)rwlock)->lock),lock,NULL) != NULL) { + /* too late, some other thread already did it */ + RtlDeleteResource(lock); + HeapFree(GetProcessHeap(), 0, lock); + } +} + int __pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *rwlock_attr) { - P_OUTPUT("FIXME:pthread_rwlock_init\n"); + ((wine_rwlock)rwlock)->lock = NULL; return 0; } strong_alias(__pthread_rwlock_init, pthread_rwlock_init); int __pthread_rwlock_destroy(pthread_rwlock_t *rwlock) { - P_OUTPUT("FIXME:pthread_rwlock_destroy\n"); + if (!((wine_rwlock)rwlock)->lock) return 0; + RtlDeleteResource(((wine_rwlock)rwlock)->lock); + HeapFree(GetProcessHeap(), 0, ((wine_rwlock)rwlock)->lock); return 0; } strong_alias(__pthread_rwlock_destroy, pthread_rwlock_destroy); int __pthread_rwlock_rdlock(pthread_rwlock_t *rwlock) { - P_OUTPUT("FIXME:pthread_rwlock_rdlock\n"); - return 0; + if (!init_done) return 0; + if (!((wine_rwlock)rwlock)->lock) + rwlock_real_init( rwlock ); + + while(TRUE) + if (RtlAcquireResourceShared(((wine_rwlock)rwlock)->lock, TRUE)) + return 0; } strong_alias(__pthread_rwlock_rdlock, pthread_rwlock_rdlock); int __pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock) { - P_OUTPUT("FIXME:pthread_rwlock_tryrdlock\n"); + if (!init_done) return 0; + if (!((wine_rwlock)rwlock)->lock) + rwlock_real_init( rwlock ); + + if (!RtlAcquireResourceShared(((wine_rwlock)rwlock)->lock, FALSE)) { + errno = EBUSY; + return -1; + } return 0; } strong_alias(__pthread_rwlock_tryrdlock, pthread_rwlock_tryrdlock); int __pthread_rwlock_wrlock(pthread_rwlock_t *rwlock) { - P_OUTPUT("FIXME:pthread_wrlock_rdlock\n"); - return 0; + if (!init_done) return 0; + if (!((wine_rwlock)rwlock)->lock) + rwlock_real_init( rwlock ); + + while(TRUE) + if (RtlAcquireResourceExclusive(((wine_rwlock)rwlock)->lock, TRUE)) + return 0; } strong_alias(__pthread_rwlock_wrlock, pthread_rwlock_wrlock); int __pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock) { - P_OUTPUT("FIXME:pthread_rwlock_trywrlock\n"); + if (!init_done) return 0; + if (!((wine_rwlock)rwlock)->lock) + rwlock_real_init( rwlock ); + + if (!RtlAcquireResourceExclusive(((wine_rwlock)rwlock)->lock, FALSE)) { + errno = EBUSY; + return -1; + } return 0; } strong_alias(__pthread_rwlock_trywrlock, pthread_rwlock_trywrlock); int __pthread_rwlock_unlock(pthread_rwlock_t *rwlock) { - P_OUTPUT("FIXME:pthread_rwlock_unlock\n"); + if (!((wine_rwlock)rwlock)->lock) return 0; + RtlReleaseResource( ((wine_rwlock)rwlock)->lock ); return 0; } strong_alias(__pthread_rwlock_unlock, pthread_rwlock_unlock); -- Jukka Heinonen <http://www.iki.fi/jhei/>