MongoDB  2.7.0
ticketholder.h
1 /* Copyright 2009 10gen Inc.
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #pragma once
16 
17 #include <boost/thread/condition_variable.hpp>
18 #include <iostream>
19 
20 #include "mongo/util/concurrency/mutex.h"
21 
22 namespace mongo {
23 
24  class TicketHolder {
25  public:
26  TicketHolder( int num ) : _mutex("TicketHolder") {
27  _outof = num;
28  _num = num;
29  }
30 
31  bool tryAcquire() {
32  scoped_lock lk( _mutex );
33  return _tryAcquire();
34  }
35 
36  void waitForTicket() {
37  scoped_lock lk( _mutex );
38 
39  while( ! _tryAcquire() ) {
40  _newTicket.wait( lk.boost() );
41  }
42  }
43 
44  void release() {
45  {
46  scoped_lock lk( _mutex );
47  _num++;
48  }
49  _newTicket.notify_one();
50  }
51 
52  void resize( int newSize ) {
53  {
54  scoped_lock lk( _mutex );
55 
56  int used = _outof - _num;
57  if ( used > newSize ) {
58  std::cout << "can't resize since we're using (" << used << ") more than newSize(" << newSize << ")" << std::endl;
59  return;
60  }
61 
62  _outof = newSize;
63  _num = _outof - used;
64  }
65 
66  // Potentially wasteful, but easier to see is correct
67  _newTicket.notify_all();
68  }
69 
70  int available() const {
71  return _num;
72  }
73 
74  int used() const {
75  return _outof - _num;
76  }
77 
78  int outof() const { return _outof; }
79 
80  private:
81 
82  bool _tryAcquire(){
83  if ( _num <= 0 ) {
84  if ( _num < 0 ) {
85  std::cerr << "DISASTER! in TicketHolder" << std::endl;
86  }
87  return false;
88  }
89  _num--;
90  return true;
91  }
92 
93  int _outof;
94  int _num;
95  mongo::mutex _mutex;
96  boost::condition_variable_any _newTicket;
97  };
98 
99  class ScopedTicket {
100  public:
101 
102  ScopedTicket(TicketHolder* holder) : _holder(holder) {
103  _holder->waitForTicket();
104  }
105 
106  ~ScopedTicket() {
107  _holder->release();
108  }
109 
110  private:
111  TicketHolder* _holder;
112  };
113 
115  public:
116  TicketHolderReleaser( TicketHolder * holder ) {
117  _holder = holder;
118  }
119 
121  _holder->release();
122  }
123  private:
124  TicketHolder * _holder;
125  };
126 }
Definition: ticketholder.h:99
Definition: ticketholder.h:24
Definition: mutex.h:101
On pthread systems, it is an error to destroy a mutex while held (boost mutex may use pthread)...
Definition: mutex.h:74
Definition: ticketholder.h:114