You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@apr.apache.org by Justin Erenkrantz <je...@ebuilt.com> on 2001/05/08 00:30:23 UTC

[REPOST] Implementation of RW locks...

To rehash the previous conversations, apr_lock.h had a comment about
RW locks, but no implementation.  This is an implementation of
POSIX RW locks, which adds apr_lock_acquire_rw() and related enums. 

I think Christian has a corresponding patch that provides RW locking 
for Win32.  I know that Bill had some comments about that patch - 
I'm not sure what the final word was.

Anyone have anything to add on the Unix side?  I think Greg was 
just getting back from Vegas when I first posted (I just got back
this afternoon from Sin City - woo-hoo!), so this might have slipped 
through the first time...  -- justin

Index: configure.in
===================================================================
RCS file: /home/cvspublic/apr/configure.in,v
retrieving revision 1.294
diff -u -r1.294 configure.in
--- configure.in	2001/04/27 18:36:03	1.294
+++ configure.in	2001/04/29 01:44:00
@@ -259,7 +259,7 @@
     if test "$pthreadh" = "1"; then
         APR_CHECK_PTHREAD_GETSPECIFIC_TWO_ARGS
         APR_CHECK_PTHREAD_ATTR_GETDETACHSTATE_ONE_ARG
-        AC_CHECK_FUNCS(pthread_key_delete)
+        AC_CHECK_FUNCS(pthread_key_delete pthread_rwlock_init)
     fi
 fi
 
Index: include/apr_lock.h
===================================================================
RCS file: /home/cvspublic/apr/include/apr_lock.h,v
retrieving revision 1.23
diff -u -r1.23 apr_lock.h
--- include/apr_lock.h	2001/02/16 04:15:46	1.23
+++ include/apr_lock.h	2001/04/29 01:44:01
@@ -71,6 +71,8 @@
 
 typedef enum {APR_MUTEX, APR_READWRITE} apr_locktype_e;
 
+typedef enum {APR_READER, APR_WRITER} apr_readerwriter_e;
+
 typedef struct apr_lock_t           apr_lock_t;
 
 /*   Function definitions */
@@ -110,6 +112,15 @@
  * @deffunc apr_status_t apr_lock_acquire(apr_lock_t *lock)
  */
 APR_DECLARE(apr_status_t) apr_lock_acquire(apr_lock_t *lock);
+
+/**
+ * Lock a region with either a reader or writer lock.
+ * @param lock The lock to set.
+ * @param type The type of lock to acquire.
+ * @deffunc apr_status_t apr_lock_acquire_rw(apr_lock_t *lock, apr_readerwriter_e type)
+ */
+APR_DECLARE(apr_status_t) apr_lock_acquire_rw(apr_lock_t *lock,
+                                              apr_readerwriter_e type);
 
 /**
  * Unlock a protected region.
Index: include/arch/unix/locks.h
===================================================================
RCS file: /home/cvspublic/apr/include/arch/unix/locks.h,v
retrieving revision 1.26
diff -u -r1.26 locks.h
--- include/arch/unix/locks.h	2001/02/25 20:39:32	1.26
+++ include/arch/unix/locks.h	2001/04/29 01:44:01
@@ -130,9 +130,12 @@
 #if APR_USE_PTHREAD_SERIALIZE
     pthread_mutex_t *intraproc;
 #endif
+#ifdef HAVE_PTHREAD_RWLOCK_INIT
+    pthread_rwlock_t rwlock;
 #endif
+#endif
     /* At some point, we should do a scope for both inter and intra process
-     *  locking here.  Something like pthread_mutex with PTHREAD_PROCESS_SHARED
+     * locking here.  Something like pthread_mutex with PTHREAD_PROCESS_SHARED
      */    
 };
 
@@ -149,8 +152,8 @@
 apr_status_t apr_unix_unlock_inter(struct apr_lock_t *lock);
 apr_status_t apr_unix_destroy_inter_lock(struct apr_lock_t *lock);
 
-apr_status_t apr_unix_child_init_lock(struct apr_lock_t **lock, apr_pool_t *cont, 
-                            const char *fname);
+apr_status_t apr_unix_child_init_lock(struct apr_lock_t **lock, 
+                                      apr_pool_t *cont, const char *fname);
 
 #endif  /* LOCKS_H */
 
Index: locks/beos/locks.c
===================================================================
RCS file: /home/cvspublic/apr/locks/beos/locks.c,v
retrieving revision 1.26
diff -u -r1.26 locks.c
--- locks/beos/locks.c	2001/02/16 04:15:53	1.26
+++ locks/beos/locks.c	2001/04/29 01:44:01
@@ -103,6 +103,11 @@
     return APR_SUCCESS;
 }
 
+apr_status_t apr_lock_acquire_rw(apr_lock_t *lock, apr_readerwriter_e e)
+{
+    return APR_ENOTIMPL;
+}
+
 apr_status_t apr_lock_release(apr_lock_t *lock)
 {
     apr_status_t stat;
Index: locks/os2/locks.c
===================================================================
RCS file: /home/cvspublic/apr/locks/os2/locks.c,v
retrieving revision 1.27
diff -u -r1.27 locks.c
--- locks/os2/locks.c	2001/03/19 12:43:25	1.27
+++ locks/os2/locks.c	2001/04/29 01:44:02
@@ -142,7 +142,10 @@
     return APR_OS2_STATUS(rc);
 }
 
-
+apr_status_t apr_lock_acquire_rw(apr_lock_t *lock, apr_readerwriter_e e)
+{
+    return APR_ENOTIMPL;
+}
 
 apr_status_t apr_lock_release(apr_lock_t *lock)
 {
Index: locks/unix/locks.c
===================================================================
RCS file: /home/cvspublic/apr/locks/unix/locks.c,v
retrieving revision 1.46
diff -u -r1.46 locks.c
--- locks/unix/locks.c	2001/02/16 04:15:55	1.46
+++ locks/unix/locks.c	2001/04/29 01:44:02
@@ -68,6 +68,9 @@
     new->cntxt = cont;
     new->type  = type;
     new->scope = scope;
+    switch (new->type)
+    {
+    case APR_MUTEX:
 #if (APR_USE_FCNTL_SERIALIZE) || (APR_USE_FLOCK_SERIALIZE)
     /* file-based serialization primitives */
     if (scope != APR_INTRAPROCESS) {
@@ -97,6 +100,18 @@
             return stat;
         }
     }
+    break;
+    case APR_READWRITE:
+#ifdef HAVE_PTHREAD_RWLOCK_INIT
+    if (scope != APR_INTRAPROCESS)
+        return APR_ENOTIMPL;
+    pthread_rwlock_init(&new->rwlock, NULL);
+    break;
+#else
+    return APR_ENOTIMPL;
+#endif
+    }
+
     *lock = new;
     return APR_SUCCESS;
 }
@@ -104,6 +119,10 @@
 apr_status_t apr_lock_acquire(apr_lock_t *lock)
 {
     apr_status_t stat;
+
+    switch (lock->type)
+    {
+    case APR_MUTEX:
 #if APR_PROCESS_LOCK_IS_GLOBAL /* don't need intra lock for APR_LOCKALL */
     if (lock->scope == APR_INTRAPROCESS) {
 #else
@@ -122,13 +141,49 @@
             return stat;
         }
     }
+    break;
+    case APR_READWRITE:
+        return APR_ENOTIMPL;
+    }
+
     return APR_SUCCESS;
 }
 
+apr_status_t apr_lock_acquire_rw(apr_lock_t *lock, apr_readerwriter_e e)
+{
+    apr_status_t stat = APR_SUCCESS;
+
+    switch (lock->type)
+    {
+    case APR_MUTEX:
+        return APR_ENOTIMPL;
+    case APR_READWRITE:
+#ifdef HAVE_PTHREAD_RWLOCK_INIT
+        switch (e)
+        {
+        case APR_READER:
+            stat = pthread_rwlock_rdlock(&lock->rwlock);
+            break;
+        case APR_WRITER:
+            stat = pthread_rwlock_wrlock(&lock->rwlock);
+            break;
+        }
+        break;
+#else
+        return APR_ENOTIMPL;
+#endif
+    }
+
+    return stat;
+}
+
 apr_status_t apr_lock_release(apr_lock_t *lock)
 {
     apr_status_t stat;
 
+    switch (lock->type)
+    {
+    case APR_MUTEX:
 #if APR_PROCESS_LOCK_IS_GLOBAL /* don't need intra lock for APR_LOCKALL */
     if (lock->scope == APR_INTRAPROCESS) {
 #else
@@ -147,12 +202,27 @@
             return stat;
         }
     }
+    break;
+    case APR_READWRITE:
+#ifdef HAVE_PTHREAD_RWLOCK_INIT
+        if ((stat = pthread_rwlock_unlock(&lock->rwlock)) != 0)
+            return stat;
+        break;
+#else
+        return APR_ENOTIMPL;
+#endif
+    }
+    
     return APR_SUCCESS;
 }
 
 apr_status_t apr_lock_destroy(apr_lock_t *lock)
 {
     apr_status_t stat;
+
+    switch (lock->type)
+    {
+    case APR_MUTEX:
 #if APR_PROCESS_LOCK_IS_GLOBAL /* don't need intra lock for APR_LOCKALL */
     if (lock->scope == APR_INTRAPROCESS) {
 #else
@@ -172,6 +242,16 @@
         if ((stat = apr_unix_destroy_inter_lock(lock)) != APR_SUCCESS) {
             return stat;
         }
+    }
+    break;
+    case APR_READWRITE:
+#ifdef HAVE_PTHREAD_RWLOCK_INIT
+    if ((stat = pthread_rwlock_destroy(&lock->rwlock)) != 0)
+        return stat;
+    break;
+#else
+    return APR_ENOTIMPL;
+#endif
     }
     return APR_SUCCESS;
 }
Index: locks/win32/locks.c
===================================================================
RCS file: /home/cvspublic/apr/locks/win32/locks.c,v
retrieving revision 1.36
diff -u -r1.36 locks.c
--- locks/win32/locks.c	2001/02/16 04:15:56	1.36
+++ locks/win32/locks.c	2001/04/29 01:44:02
@@ -131,6 +131,12 @@
     return apr_get_os_error();
 }
 
+APR_DECLARE(apr_status_t) apr_lock_acquire_rw(apr_lock_t *lock,
+                                              apr_readerwriter_e e)
+{
+    return APR_ENOTIMPL;
+}
+
 APR_DECLARE(apr_status_t) apr_lock_release(apr_lock_t *lock)
 {
     if (lock->scope == APR_INTRAPROCESS) {