You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by dr...@apache.org on 2001/10/28 14:05:51 UTC

cvs commit: apr/locks/beos proc_mutex.c thread_mutex.c thread_rwlock.c

dreid       01/10/28 05:05:51

  Modified:    locks/beos proc_mutex.c thread_mutex.c thread_rwlock.c
  Log:
  Add the actual code for most of the new lock methods.  Just the conditional
  implementation to add at some point.
  
  Revision  Changes    Path
  1.4       +65 -6     apr/locks/beos/proc_mutex.c
  
  Index: proc_mutex.c
  ===================================================================
  RCS file: /home/cvs/apr/locks/beos/proc_mutex.c,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- proc_mutex.c	2001/10/19 23:25:28	1.3
  +++ proc_mutex.c	2001/10/28 13:05:51	1.4
  @@ -60,13 +60,51 @@
   #include "apr_strings.h"
   #include "apr_portable.h"
   
  +static apr_status_t _proc_mutex_cleanup(void * data)
  +{
  +    apr_proc_mutex_t *lock = (apr_proc_mutex_t*)data;
  +    if (lock->LockCount != 0) {
  +        /* we're still locked... */
  +    	while (atomic_add(&lock->LockCount , -1) > 1){
  +    	    /* OK we had more than one person waiting on the lock so 
  +    	     * the sem is also locked. Release it until we have no more
  +    	     * locks left.
  +    	     */
  +            release_sem (lock->Lock);
  +    	}
  +    }
  +    delete_sem(lock->Lock);
  +    return APR_SUCCESS;
  +}    
  +
   APR_DECLARE(apr_status_t) apr_proc_mutex_create(apr_proc_mutex_t **mutex,
                                                   const char *fname,
                                                   apr_pool_t *pool)
   {
  -    return APR_ENOTIMPL;
  +    apr_proc_mutex_t *new;
  +    apr_status_t stat = APR_SUCCESS;
  +  
  +    new = (apr_proc_mutex_t *)apr_pcalloc(pool, sizeof(apr_proc_mutex_t));
  +    if (new == NULL){
  +        return APR_ENOMEM;
  +    }
  +    
  +    if ((stat = create_sem(0, "APR_Lock")) < B_NO_ERROR) {
  +        _proc_mutex_cleanup(new);
  +        return stat;
  +    }
  +    new->LockCount = 0;
  +    new->Lock = stat;  
  +    new->pool  = pool;
  +
  +    apr_pool_cleanup_register(new->pool, (void *)new, _proc_mutex_cleanup,
  +                              apr_pool_cleanup_null);
  +
  +    (*mutex) = new;
  +    return APR_SUCCESS;
   }
   
  +#if APR_HAS_CREATE_LOCKS_NP
   APR_DECLARE(apr_status_t) apr_proc_mutex_create_np(apr_proc_mutex_t **mutex,
                                                      const char *fname,
                                                      apr_lockmech_e_np mech,
  @@ -74,6 +112,7 @@
   {
       return APR_ENOTIMPL;
   }       
  +#endif
   
   APR_DECLARE(apr_status_t) apr_proc_mutex_child_init(apr_proc_mutex_t **mutex,
                                                       const char *fname,
  @@ -84,7 +123,15 @@
       
   APR_DECLARE(apr_status_t) apr_proc_mutex_lock(apr_proc_mutex_t *mutex)
   {
  -    return APR_ENOTIMPL;
  +    int32 stat;
  +    
  +	if (atomic_add(&mutex->LockCount, 1) > 0) {
  +		if ((stat = acquire_sem(mutex->Lock)) < B_NO_ERROR) {
  +		    atomic_add(&mutex->LockCount, -1);
  +		    return stat;
  +		}
  +	}
  +    return APR_SUCCESS;
   }
   
   APR_DECLARE(apr_status_t) apr_proc_mutex_trylock(apr_proc_mutex_t *mutex)
  @@ -94,12 +141,25 @@
   
   APR_DECLARE(apr_status_t) apr_proc_mutex_unlock(apr_proc_mutex_t *mutex)
   {
  -    return APR_ENOTIMPL;
  +    int32 stat;
  +    
  +	if (atomic_add(&mutex->LockCount, -1) > 1) {
  +        if ((stat = release_sem(mutex->Lock)) < B_NO_ERROR) {
  +            atomic_add(&mutex->LockCount, 1);
  +            return stat;
  +        }
  +    }
  +    return APR_SUCCESS;
   }
   
   APR_DECLARE(apr_status_t) apr_proc_mutex_destroy(apr_proc_mutex_t *mutex)
   {
  -    return APR_ENOTIMPL;
  +    apr_status_t stat;
  +    if ((stat = _proc_mutex_cleanup(mutex)) == APR_SUCCESS) {
  +        apr_pool_cleanup_kill(mutex->pool, mutex, _proc_mutex_cleanup);
  +        return APR_SUCCESS;
  +    }
  +    return stat;
   }
   
   APR_POOL_IMPLEMENT_ACCESSOR(proc_mutex)
  @@ -122,8 +182,7 @@
           return APR_ENOPOOL;
       }
       if ((*pmutex) == NULL) {
  -        (*pmutex) = (apr_proc_mutex_t *)apr_pcalloc(pool,
  -                                                    sizeof(apr_proc_mutex_t));
  +        (*pmutex) = (apr_proc_mutex_t *)apr_pcalloc(pool, sizeof(apr_proc_mutex_t));
           (*pmutex)->pool = pool;
       }
       (*pmutex)->Lock = ospmutex->sem;
  
  
  
  1.4       +103 -11   apr/locks/beos/thread_mutex.c
  
  Index: thread_mutex.c
  ===================================================================
  RCS file: /home/cvs/apr/locks/beos/thread_mutex.c,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- thread_mutex.c	2001/10/17 00:33:00	1.3
  +++ thread_mutex.c	2001/10/28 13:05:51	1.4
  @@ -60,21 +60,91 @@
   #include "apr_strings.h"
   #include "apr_portable.h"
   
  -static apr_status_t thread_mutex_cleanup(void *data)
  +static apr_status_t _thread_mutex_cleanup(void * data)
   {
  -    return APR_ENOTIMPL;
  -}
  +    apr_thread_mutex_t *lock = (apr_thread_mutex_t*)data;
  +    if (lock->LockCount != 0) {
  +        /* we're still locked... */
  +    	while (atomic_add(&lock->LockCount , -1) > 1){
  +    	    /* OK we had more than one person waiting on the lock so 
  +    	     * the sem is also locked. Release it until we have no more
  +    	     * locks left.
  +    	     */
  +            release_sem (lock->Lock);
  +    	}
  +    }
  +    delete_sem(lock->Lock);
  +    return APR_SUCCESS;
  +}    
   
   APR_DECLARE(apr_status_t) apr_thread_mutex_create(apr_thread_mutex_t **mutex,
                                                     unsigned int flags,
                                                     apr_pool_t *pool)
   {
  -    return APR_ENOTIMPL;
  +    apr_thread_mutex_t *new_m;
  +    apr_status_t stat = APR_SUCCESS;
  +  
  +    new_m = (apr_thread_mutex_t *)apr_pcalloc(pool, sizeof(apr_thread_mutex_t));
  +    if (new_m == NULL){
  +        return APR_ENOMEM;
  +    }
  +    
  +    if ((stat = create_sem(0, "APR_Lock")) < B_NO_ERROR) {
  +        _thread_mutex_cleanup(new_m);
  +        return stat;
  +    }
  +    new_m->LockCount = 0;
  +    new_m->Lock = stat;  
  +    new_m->pool  = pool;
  +    new_m->nested = flags & APR_THREAD_MUTEX_NESTED;
  +
  +    apr_pool_cleanup_register(new_m->pool, (void *)new_m, _thread_mutex_cleanup,
  +                              apr_pool_cleanup_null);
  +
  +    (*mutex) = new_m;
  +    return APR_SUCCESS;
  +}
  +
  +#if APR_HAS_CREATE_LOCKS_NP
  +APR_DECLARE(apr_status_t) apr_thread_mutex_create_np(apr_thread_mutex_t **mutex,
  +                                                   const char *fname,
  +                                                   apr_lockmech_e_np mech,
  +                                                   apr_pool_t *pool)
  +{
  +    return APR_ENOTIMPL;
  +}       
  +#endif
  +
  +APR_DECLARE(apr_status_t) apr_thread_mutex_child_init(apr_thread_mutex_t **mutex,
  +                                                    const char *fname,
  +                                                    apr_pool_t *pool)
  +{
  +    return APR_SUCCESS;
   }
  -
  +    
   APR_DECLARE(apr_status_t) apr_thread_mutex_lock(apr_thread_mutex_t *mutex)
   {
  -    return APR_ENOTIMPL;
  +    int32 stat;
  +    
  +    if (mutex->nested && mutex->owner == find_thread(NULL)) {
  +        mutex->owner_ref++;
  +        return APR_SUCCESS;
  +    }
  +    
  +	if (atomic_add(&mutex->LockCount, 1) > 0) {
  +		if ((stat = acquire_sem(mutex->Lock)) < B_NO_ERROR) {
  +            /* Oh dear, acquire_sem failed!!  */
  +		    atomic_add(&mutex->LockCount, -1);
  +		    return stat;
  +		}
  +	}
  +
  +    if (mutex->nested) {
  +        mutex->owner = find_thread(NULL);
  +        mutex->owner_ref = 1;
  +    }
  +    
  +    return APR_SUCCESS;
   }
   
   APR_DECLARE(apr_status_t) apr_thread_mutex_trylock(apr_thread_mutex_t *mutex)
  @@ -84,13 +154,35 @@
   
   APR_DECLARE(apr_status_t) apr_thread_mutex_unlock(apr_thread_mutex_t *mutex)
   {
  -    return APR_ENOTIMPL;
  +    int32 stat;
  +    
  +    if (mutex->nested && mutex->owner == find_thread(NULL)) {
  +        mutex->owner_ref--;
  +        if (mutex->owner_ref > 0)
  +            return APR_SUCCESS;
  +    }
  +    
  +	if (atomic_add(&mutex->LockCount, -1) > 1) {
  +        if ((stat = release_sem(mutex->Lock)) < B_NO_ERROR) {
  +            atomic_add(&mutex->LockCount, 1);
  +            return stat;
  +        }
  +    }
  +
  +    if (mutex->nested) {
  +        mutex->owner = -1;
  +        mutex->owner_ref = 0;
  +    }
  +
  +    return APR_SUCCESS;
   }
   
   APR_DECLARE(apr_status_t) apr_thread_mutex_destroy(apr_thread_mutex_t *mutex)
   {
  -    return APR_ENOTIMPL;
  +    apr_status_t stat;
  +    if ((stat = _thread_mutex_cleanup(mutex)) == APR_SUCCESS) {
  +        apr_pool_cleanup_kill(mutex->pool, mutex, _thread_mutex_cleanup);
  +        return APR_SUCCESS;
  +    }
  +    return stat;
   }
  -
  -APR_POOL_IMPLEMENT_ACCESSOR(thread_mutex)
  -
  
  
  
  1.3       +133 -5    apr/locks/beos/thread_rwlock.c
  
  Index: thread_rwlock.c
  ===================================================================
  RCS file: /home/cvs/apr/locks/beos/thread_rwlock.c,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- thread_rwlock.c	2001/09/29 05:04:44	1.2
  +++ thread_rwlock.c	2001/10/28 13:05:51	1.3
  @@ -60,15 +60,82 @@
   #include "apr_strings.h"
   #include "apr_portable.h"
   
  +#define BIG_NUM 100000
  +
  +static apr_status_t _thread_rw_cleanup(void * data)
  +{
  +    apr_thread_rwlock_t *mutex = (apr_thread_rwlock_t*)data;
  +
  +    if (mutex->ReadCount != 0) {
  +    	while (atomic_add(&mutex->ReadCount , -1) > 1){
  +            release_sem (mutex->Read);
  +    	}
  +    }
  +    if (mutex->WriteCount != 0) {
  +    	while (atomic_add(&mutex->WriteCount , -1) > 1){
  +            release_sem (mutex->Write);
  +    	}
  +    }
  +    if (mutex->LockCount != 0) {
  +    	while (atomic_add(&mutex->LockCount , -1) > 1){
  +            release_sem (mutex->Lock);
  +    	}
  +    }
  +    
  +    delete_sem(mutex->Read);
  +    delete_sem(mutex->Write);
  +    delete_sem(mutex->Lock);
  +    return APR_SUCCESS;
  +}    
  +
   APR_DECLARE(apr_status_t) apr_thread_rwlock_create(apr_thread_rwlock_t **rwlock,
                                                      apr_pool_t *pool)
   {
  -    return APR_ENOTIMPL;
  +    apr_thread_rwlock_t *new;
  +  
  +    new = (apr_thread_rwlock_t *)apr_pcalloc(pool, sizeof(apr_thread_rwlock_t));
  +    if (new == NULL){
  +        return APR_ENOMEM;
  +    }
  +    
  +    new->pool  = pool;
  +    /* we need to make 3 locks... */
  +    new->ReadCount = 0;
  +    new->WriteCount = 0;
  +    new->LockCount = 0;
  +    new->Read  = create_sem(0, "APR_ReadLock");
  +    new->Write = create_sem(0, "APR_WriteLock");
  +    new->Lock  = create_sem(0, "APR_Lock");
  +    
  +    if (new->Lock < 0 || new->Read < 0 || new->Write < 0) {
  +        _thread_rw_cleanup(new);
  +        return -1;
  +    }
  +
  +    apr_pool_cleanup_register(new->pool, (void *)new, _thread_rw_cleanup,
  +                              apr_pool_cleanup_null);
  +    (*rwlock) = new;
  +    return APR_SUCCESS;
   }
   
   APR_DECLARE(apr_status_t) apr_thread_rwlock_rdlock(apr_thread_rwlock_t *rwlock)
   {
  -    return APR_ENOTIMPL;
  +    int32 rv = APR_SUCCESS;
  +
  +    if (find_thread(NULL) == rwlock->writer) {
  +        /* we're the writer - no problem */
  +        rwlock->Nested++;
  +    } else {
  +        /* we're not the writer */
  +        int32 r = atomic_add(&rwlock->ReadCount, 1);
  +        if (r < 0) {
  +            /* Oh dear, writer holds lock, wait for sem */
  +            rv = acquire_sem_etc(rwlock->Read, 1, B_DO_NOT_RESCHEDULE,
  +                                 B_INFINITE_TIMEOUT);
  +        }
  +    }
  +
  +    return rv;
   }
   
   APR_DECLARE(apr_status_t) apr_thread_rwlock_tryrdlock(apr_thread_rwlock_t *rwlock)
  @@ -78,7 +145,33 @@
   
   APR_DECLARE(apr_status_t) apr_thread_rwlock_wrlock(apr_thread_rwlock_t *rwlock)
   {
  -    return APR_ENOTIMPL;
  +    int rv = APR_SUCCESS;
  +
  +    if (find_thread(NULL) == rwlock->writer) {
  +        rwlock->Nested++;
  +    } else {
  +        /* we're not the writer... */
  +        if (atomic_add(&rwlock->LockCount, 1) >= 1) {
  +            /* we're locked - acquire the sem */
  +            rv = acquire_sem_etc(rwlock->Lock, 1, B_DO_NOT_RESCHEDULE,
  +                                 B_INFINITE_TIMEOUT);
  +        }
  +        if (rv == APR_SUCCESS) {
  +            /* decrement the ReadCount to a large -ve number so that
  +             * we block on new readers...
  +             */
  +            int32 readers = atomic_add(&rwlock->ReadCount, -BIG_NUM);
  +            if (readers > 0) {
  +                /* readers are holding the lock */
  +                rv = acquire_sem_etc(rwlock->Write, readers, B_DO_NOT_RESCHEDULE,
  +                                     B_INFINITE_TIMEOUT);
  +            }
  +            if (rv == APR_SUCCESS)
  +                rwlock->writer = find_thread(NULL);
  +        }
  +    }
  +    
  +    return rv;
   }
   
   APR_DECLARE(apr_status_t) apr_thread_rwlock_trywrlock(apr_thread_rwlock_t *rwlock)
  @@ -88,12 +181,47 @@
   
   APR_DECLARE(apr_status_t) apr_thread_rwlock_unlock(apr_thread_rwlock_t *rwlock)
   {
  -    return APR_ENOTIMPL;
  +    apr_status_t rv = APR_SUCCESS;
  +    int32 readers;
  +
  +    /* we know we hold the lock, so don't check it :) */
  +    if (find_thread(NULL) == rwlock->writer) {
  +    /* we know we hold the lock, so don't check it :) */
  +        if (rwlock->Nested > 1) {
  +            /* we're recursively locked */
  +            rwlock->Nested--;
  +            return APR_SUCCESS;
  +        }
  +        /* OK so we need to release the sem if we have it :) */
  +        readers = atomic_add(&rwlock->ReadCount, BIG_NUM) + BIG_NUM;
  +        if (readers > 0) {
  +            rv = release_sem_etc(rwlock->Read, readers, B_DO_NOT_RESCHEDULE);
  +        }
  +        if (rv == APR_SUCCESS) {
  +            rwlock->writer = -1;
  +            if (atomic_add(&rwlock->LockCount, -1) > 1) {
  +                rv = release_sem_etc(rwlock->Lock, 1, B_DO_NOT_RESCHEDULE);
  +            }
  +        }
  +    } else {
  +       /* We weren't the Writer, so just release the ReadCount... */
  +       if (atomic_add(&rwlock->ReadCount, -1) < 0) {
  +            /* we have a writer waiting for the lock, so release it */
  +            rv = release_sem_etc(rwlock->Write, 1, B_DO_NOT_RESCHEDULE);
  +        }
  +    }
  +
  +    return rv;
   }
   
   APR_DECLARE(apr_status_t) apr_thread_rwlock_destroy(apr_thread_rwlock_t *rwlock)
   {
  -    return APR_ENOTIMPL;
  +    apr_status_t stat;
  +    if ((stat = _thread_rw_cleanup(rwlock)) == APR_SUCCESS) {
  +        apr_pool_cleanup_kill(rwlock->pool, rwlock, _thread_rw_cleanup);
  +        return APR_SUCCESS;
  +    }
  +    return stat;
   }
   
   APR_POOL_IMPLEMENT_ACCESSOR(thread_rwlock)