Shadowrun: Awakened 29 September 2011 - Build 871
reader_writer_lock.h
Go to the documentation of this file.
00001 /*
00002     Copyright 2005-2010 Intel Corporation.  All Rights Reserved.
00003 
00004     This file is part of Threading Building Blocks.
00005 
00006     Threading Building Blocks is free software; you can redistribute it
00007     and/or modify it under the terms of the GNU General Public License
00008     version 2 as published by the Free Software Foundation.
00009 
00010     Threading Building Blocks is distributed in the hope that it will be
00011     useful, but WITHOUT ANY WARRANTY; without even the implied warranty
00012     of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with Threading Building Blocks; if not, write to the Free Software
00017     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00018 
00019     As a special exception, you may use this file as part of a free software
00020     library without restriction.  Specifically, if other files instantiate
00021     templates or use macros or inline functions from this file, or you compile
00022     this file and link it with other files to produce an executable, this
00023     file does not by itself cause the resulting executable to be covered by
00024     the GNU General Public License.  This exception does not however
00025     invalidate any other reasons why the executable file might be covered by
00026     the GNU General Public License.
00027 */
00028 
00029 #ifndef __TBB_reader_writer_lock_H
00030 #define __TBB_reader_writer_lock_H
00031 
00032 #include "tbb_thread.h"
00033 #include "tbb_allocator.h"
00034 #include "atomic.h"
00035 
00036 namespace tbb {
00037 namespace interface5 {
00039 
00042     class reader_writer_lock : tbb::internal::no_copy {
00043  public:
00044     friend class scoped_lock;
00045     friend class scoped_lock_read;
00047 
00082     enum status_t { waiting_nonblocking, waiting, active, invalid };
00083 
00085     reader_writer_lock() {
00086         internal_construct();
00087     }
00088 
00090     ~reader_writer_lock() {
00091         internal_destroy();
00092     }
00093 
00095 
00097     class scoped_lock : tbb::internal::no_copy {
00098     public:
00099         friend class reader_writer_lock;
00100  
00102         scoped_lock(reader_writer_lock& lock) {
00103             internal_construct(lock);
00104         }
00105         
00107         ~scoped_lock() {
00108             internal_destroy();
00109         }
00110 
00111         void* operator new(size_t s) {
00112             return tbb::internal::allocate_via_handler_v3(s);
00113         }
00114         void operator delete(void* p) {
00115             tbb::internal::deallocate_via_handler_v3(p);
00116         }
00117 
00118     private:
00120         reader_writer_lock *mutex;
00122         scoped_lock* next;
00124         atomic<status_t> status;
00125 
00127         scoped_lock();
00128 
00129         void __TBB_EXPORTED_METHOD internal_construct(reader_writer_lock&);
00130         void __TBB_EXPORTED_METHOD internal_destroy();
00131    };
00132 
00134     class scoped_lock_read : tbb::internal::no_copy {
00135     public:
00136         friend class reader_writer_lock;
00137 
00139         scoped_lock_read(reader_writer_lock& lock) {
00140             internal_construct(lock);
00141         }
00142 
00144         ~scoped_lock_read() { 
00145             internal_destroy();
00146         }
00147         
00148         void* operator new(size_t s) {
00149             return tbb::internal::allocate_via_handler_v3(s);
00150         }
00151         void operator delete(void* p) {
00152             tbb::internal::deallocate_via_handler_v3(p);
00153         }
00154 
00155     private:
00157         reader_writer_lock *mutex;
00159         scoped_lock_read *next;
00161         atomic<status_t> status;
00162 
00164         scoped_lock_read();
00165 
00166         void __TBB_EXPORTED_METHOD internal_construct(reader_writer_lock&);
00167         void __TBB_EXPORTED_METHOD internal_destroy();
00168     };
00169     
00171 
00176     void __TBB_EXPORTED_METHOD lock();
00177 
00179 
00183     bool __TBB_EXPORTED_METHOD try_lock();
00184 
00186 
00190     void __TBB_EXPORTED_METHOD lock_read(); 
00191 
00193 
00195     bool __TBB_EXPORTED_METHOD try_lock_read();
00196 
00198     void __TBB_EXPORTED_METHOD unlock();
00199 
00200  private:
00201     void __TBB_EXPORTED_METHOD internal_construct();
00202     void __TBB_EXPORTED_METHOD internal_destroy();
00203 
00205 
00206     bool start_write(scoped_lock *);
00208     void set_next_writer(scoped_lock *w);
00210     void end_write(scoped_lock *);
00212     bool is_current_writer();
00213 
00215 
00216     void start_read(scoped_lock_read *);
00218     void unblock_readers();
00220     void end_read();
00221 
00223     atomic<scoped_lock_read*> reader_head;
00225     atomic<scoped_lock*> writer_head;
00227     atomic<scoped_lock*> writer_tail;
00229     tbb_thread::id my_current_writer;
00231     atomic<unsigned> rdr_count_and_flags;
00232 };
00233 
00234 } // namespace interface5
00235 
00236 using interface5::reader_writer_lock;
00237 
00238 } // namespace tbb
00239 
00240 #endif /* __TBB_reader_writer_lock_H */

Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.

GNU Lesser General Public License 3 Sourceforge.net