• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

ink_rwlock.cc

Go to the documentation of this file.
00001 /** @file
00002 
00003   A brief file description
00004 
00005   @section license License
00006 
00007   Licensed to the Apache Software Foundation (ASF) under one
00008   or more contributor license agreements.  See the NOTICE file
00009   distributed with this work for additional information
00010   regarding copyright ownership.  The ASF licenses this file
00011   to you under the Apache License, Version 2.0 (the
00012   "License"); you may not use this file except in compliance
00013   with the License.  You may obtain a copy of the License at
00014 
00015       http://www.apache.org/licenses/LICENSE-2.0
00016 
00017   Unless required by applicable law or agreed to in writing, software
00018   distributed under the License is distributed on an "AS IS" BASIS,
00019   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00020   See the License for the specific language governing permissions and
00021   limitations under the License.
00022  */
00023 
00024 #include "ink_config.h"
00025 #include "ink_rwlock.h"
00026 
00027 //-------------------------------------------------------------------------
00028 // ink_rwlock_init
00029 //-------------------------------------------------------------------------
00030 
00031 int
00032 ink_rwlock_init(ink_rwlock * rw)
00033 {
00034 
00035   int result;
00036 
00037   if ((result = ink_mutex_init(&rw->rw_mutex, NULL)) != 0)
00038     goto Lerror;
00039   ink_cond_init(&rw->rw_condreaders);
00040   ink_cond_init(&rw->rw_condwriters);
00041   rw->rw_nwaitreaders = 0;
00042   rw->rw_nwaitwriters = 0;
00043   rw->rw_refcount = 0;
00044   rw->rw_magic = RW_MAGIC;
00045 
00046   return (0);
00047 
00048 Lerror:
00049   return (result);              /* an errno value */
00050 
00051 }
00052 
00053 //-------------------------------------------------------------------------
00054 // ink_rwlock_destroy
00055 //-------------------------------------------------------------------------
00056 
00057 int
00058 ink_rwlock_destroy(ink_rwlock * rw)
00059 {
00060 
00061   if (rw->rw_magic != RW_MAGIC)
00062     return (EINVAL);
00063   if (rw->rw_refcount != 0 || rw->rw_nwaitreaders != 0 || rw->rw_nwaitwriters != 0)
00064     return (EBUSY);
00065 
00066   ink_mutex_destroy(&rw->rw_mutex);
00067   ink_cond_destroy(&rw->rw_condreaders);
00068   ink_cond_destroy(&rw->rw_condwriters);
00069   rw->rw_magic = 0;
00070 
00071   return (0);
00072 }
00073 
00074 //-------------------------------------------------------------------------
00075 // ink_rwlock_rdlock
00076 //-------------------------------------------------------------------------
00077 
00078 int
00079 ink_rwlock_rdlock(ink_rwlock * rw)
00080 {
00081 
00082   int result;
00083 
00084   if (rw->rw_magic != RW_MAGIC)
00085     return (EINVAL);
00086 
00087   if ((result = ink_mutex_acquire(&rw->rw_mutex)) != 0)
00088     return (result);
00089 
00090   /* give preference to waiting writers */
00091   while (rw->rw_refcount < 0 || rw->rw_nwaitwriters > 0) {
00092     rw->rw_nwaitreaders++;
00093     ink_cond_wait(&rw->rw_condreaders, &rw->rw_mutex);
00094     rw->rw_nwaitreaders--;
00095   }
00096   rw->rw_refcount++;            /* another reader has a read lock */
00097 
00098   ink_mutex_release(&rw->rw_mutex);
00099 
00100   return (0);
00101 
00102 }
00103 
00104 //-------------------------------------------------------------------------
00105 // ink_rwlock_wrlock
00106 //-------------------------------------------------------------------------
00107 
00108 int
00109 ink_rwlock_wrlock(ink_rwlock * rw)
00110 {
00111 
00112   int result;
00113 
00114   if (rw->rw_magic != RW_MAGIC)
00115     return (EINVAL);
00116 
00117   if ((result = ink_mutex_acquire(&rw->rw_mutex)) != 0)
00118     return (result);
00119 
00120   while (rw->rw_refcount != 0) {
00121     rw->rw_nwaitwriters++;
00122     ink_cond_wait(&rw->rw_condwriters, &rw->rw_mutex);
00123     rw->rw_nwaitwriters--;
00124   }
00125   rw->rw_refcount = -1;
00126 
00127   ink_mutex_release(&rw->rw_mutex);
00128 
00129   return (0);
00130 
00131 }
00132 
00133 //-------------------------------------------------------------------------
00134 // ink_rwlock_unlock
00135 //-------------------------------------------------------------------------
00136 
00137 int
00138 ink_rwlock_unlock(ink_rwlock * rw)
00139 {
00140 
00141   int result;
00142 
00143   if (rw->rw_magic != RW_MAGIC)
00144     return (EINVAL);
00145 
00146   if ((result = ink_mutex_acquire(&rw->rw_mutex)) != 0)
00147     return (result);
00148 
00149   if (rw->rw_refcount > 0)
00150     rw->rw_refcount--;          /* releasing a reader */
00151   else if (rw->rw_refcount == -1)
00152     rw->rw_refcount = 0;        /* releasing a reader */
00153   else
00154     ink_release_assert("invalid rw_refcount!");
00155 
00156   /* give preference to waiting writers over waiting readers */
00157   if (rw->rw_nwaitwriters > 0) {
00158     if (rw->rw_refcount == 0)
00159       ink_cond_signal(&rw->rw_condwriters);
00160   } else if (rw->rw_nwaitreaders > 0)
00161     ink_cond_broadcast(&rw->rw_condreaders);
00162 
00163   ink_mutex_release(&rw->rw_mutex);
00164 
00165   return (0);
00166 
00167 }

Generated by  doxygen 1.7.1