~ubuntu-branches/ubuntu/wily/afnix/wily

« back to all changes in this revision

Viewing changes to src/lib/std/shl/obj/Lockrw.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Anibal Monsalve Salazar
  • Date: 2011-03-16 21:31:18 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20110316213118-gk4k3ez3e5d2huna
Tags: 2.0.0-1
* QA upload.
* New upstream release
* Debian source format is 3.0 (quilt)
* Fix debhelper-but-no-misc-depends
* Fix ancient-standards-version
* Fix package-contains-linda-override
* debhelper compatibility is 7
* Fix dh-clean-k-is-deprecated

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// ---------------------------------------------------------------------------
2
 
// - Lockrw.cpp                                                              -
3
 
// - standard object library - read-write lock class implementation          -
4
 
// ---------------------------------------------------------------------------
5
 
// - This program is free software;  you can redistribute it  and/or  modify -
6
 
// - it provided that this copyright notice is kept intact.                  -
7
 
// -                                                                         -
8
 
// - This program  is  distributed in  the hope  that it will be useful, but -
9
 
// - without  any  warranty;  without  even   the   implied    warranty   of -
10
 
// - merchantability or fitness for a particular purpose.  In no event shall -
11
 
// - the copyright holder be liable for any  direct, indirect, incidental or -
12
 
// - special damages arising in any way out of the use of this software.     -
13
 
// ---------------------------------------------------------------------------
14
 
// - copyright (c) 1999-2007 amaury darsch                                   -
15
 
// ---------------------------------------------------------------------------
16
 
 
17
 
#include "Lockrw.hpp"
18
 
#include "Exception.hpp"
19
 
#include "cthr.hpp"
20
 
 
21
 
namespace afnix {
22
 
 
23
 
  // -------------------------------------------------------------------------
24
 
  // - class section                                                         -
25
 
  // -------------------------------------------------------------------------
26
 
 
27
 
  // create a new read-write lock
28
 
 
29
 
  Lockrw::Lockrw (void) {
30
 
    p_tid = nilp;
31
 
    p_mtx = c_mtxcreate ();
32
 
    if (p_mtx == nilp) 
33
 
      throw Exception ("lockrw-error", "cannot create read-write lock");
34
 
    p_rcv = c_tcvcreate ();
35
 
    if (p_rcv == nilp) {
36
 
      c_mtxdestroy (p_mtx);
37
 
      throw Exception ("lockrw-error", "cannot create read-write lock");
38
 
    }
39
 
    p_wcv   = c_tcvcreate ();
40
 
    if (p_wcv == nilp) {
41
 
      c_mtxdestroy (p_mtx);
42
 
      c_tcvdestroy (p_rcv);
43
 
      throw Exception ("lockrw-error", "cannot create read-write lock");
44
 
    }
45
 
    d_rcount = 0;
46
 
    d_wcount = 0;
47
 
    d_waitrd = 0;
48
 
    d_waitwr = 0;
49
 
  }
50
 
 
51
 
  // destroy this read-write lock
52
 
 
53
 
  Lockrw::~Lockrw (void) {
54
 
    c_tcvdestroy (p_wcv);
55
 
    c_tcvdestroy (p_rcv);
56
 
    c_mtxdestroy (p_mtx);
57
 
  }
58
 
 
59
 
  // lock this read-write lock for reading
60
 
 
61
 
  void Lockrw::rdlock (void) {
62
 
    // lock this object
63
 
    c_mtxlock (p_mtx);
64
 
 
65
 
    // check if we have the write lock
66
 
    if ((d_wcount > 0) && (c_threqual (p_tid) == true)) {
67
 
      d_wcount++;
68
 
      c_mtxunlock (p_mtx);
69
 
      return;
70
 
    }
71
 
 
72
 
    // wait until the writers have finished
73
 
    while (d_wcount > 0) {
74
 
      d_waitrd++;
75
 
      c_tcvwait (p_rcv, p_mtx);
76
 
      d_waitrd--;
77
 
    }
78
 
 
79
 
    // here we have a new reader
80
 
    d_rcount++;
81
 
    c_mtxunlock (p_mtx);
82
 
  }
83
 
 
84
 
  // lock this read-write lock for writing
85
 
 
86
 
  void Lockrw::wrlock (void) {
87
 
    // lock this object
88
 
    c_mtxlock (p_mtx);
89
 
 
90
 
    // check if we have already the lock
91
 
    if ((d_wcount > 0) && (c_threqual (p_tid) == true)) {
92
 
      d_wcount++;
93
 
      c_mtxunlock (p_mtx);
94
 
      return;
95
 
    }
96
 
 
97
 
    // check if we have some readers or writers
98
 
    while ((d_rcount > 0) || (d_wcount > 0)) {
99
 
      d_waitwr++;
100
 
      c_tcvwait (p_wcv, p_mtx);
101
 
      d_waitwr--;
102
 
    }
103
 
    // here we have a new write lock
104
 
    d_wcount++;
105
 
    p_tid = c_thrself ();
106
 
    c_mtxunlock (p_mtx);
107
 
  }
108
 
 
109
 
  // unlock a read-write lock
110
 
 
111
 
  void Lockrw::unlock (void) {
112
 
    // lock this object
113
 
    c_mtxlock (p_mtx);
114
 
    
115
 
    // adjust the counters - we can only have one writer - for recursive
116
 
    // writer, we simply decrement the counter
117
 
    if (d_wcount > 0) {
118
 
      d_wcount--;
119
 
      if (d_wcount > 0) {
120
 
        c_mtxunlock (p_mtx);
121
 
        return;
122
 
      }
123
 
      p_tid = nilp;
124
 
    } else if (d_rcount > 0) d_rcount--;
125
 
 
126
 
    // give preference to waiting writers
127
 
    if (d_waitwr > 0) {
128
 
      c_tcvsignal (p_wcv);
129
 
    } else if (d_waitrd > 0) {
130
 
      c_tcvbdcast (p_rcv);
131
 
    }
132
 
    c_mtxunlock (p_mtx);
133
 
  }
134
 
}