timed_rwlock.cc

Example # 12 - timedout read/write lock functions.
This example demonstrates timedout read/write lock functions.
//
// $Id: timed_rwlock.cc,v 1.5 2003/10/30 15:05:12 cholm Exp $ 
//  
//  Test of threads - C %example ex11.c
//  Copyright (C) 2002 Christian Holm Christensen <cholm@nbi.dk> 
//
//  This library is free software; you can redistribute it and/or 
//  modify it under the terms of the GNU Lesser General Public License 
//  as published by the Free Software Foundation; either version 2.1 
//  of the License, or (at your option) any later version. 
//
//  This library is distributed in the hope that it will be useful, 
//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
//  Lesser General Public License for more details. 
// 
//  You should have received a copy of the GNU Lesser General Public 
//  License along with this library; if not, write to the Free 
//  Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 
//  02111-1307 USA 
//
#ifndef OPTION_HH
#include "option.hh"
#endif
#ifndef THREADMM_thread
#include <threadmm/thread.hh>
#endif
#ifndef THREADMM_rwlock
#include <threadmm/rwlock.hh>
#endif
#ifndef THREADMM_example_gettime
#include "gettime.hh"
#endif

using namespace std;

namespace example 
{
  threadmm::mutex io_lock;

  class rw : public threadmm::thread
  {
  public:
    enum {
      reader, 
      writer
    };
  private: 
    int _id;
    int _kind;
    int _tries;
    struct timespec _delay;
    struct timespec _wait;
  public:
    static threadmm::rwlock* _lock;

    rw(bool read, int id)  
    {
      _id    = id;
      _kind  = read ? reader : writer; 
      _tries = read ? 3 : 4; 
    }      
    void* operator()()  { 
      _wait.tv_sec   = 0;
      _wait.tv_nsec  = 1000000L;
      _delay.tv_sec  = 0;
      _delay.tv_nsec = 1000000L;

      try {
  for (int i = 0; i < _tries; i++) {
    do {
      gettime(_wait);
      _wait.tv_nsec += 2 * 1000000L;
      cout << "- " << (_kind == reader ? "reader" : "writer") 
     << " thread " << _id << " tries again" << endl;
    } while (!(_kind == reader ?  
         _lock->lock4read(&_wait) :
         _lock->lock4write(&_wait)));
    
    cout << "+ " << (_kind == reader ? "reader" : "writer") 
         << " thread " << _id << " succeded" << endl;
    nanosleep(&_delay, NULL);
    if (!_lock->unlock()) cerr << "Failed to unlock" << std::endl;
    
    cout << "! " << (_kind == reader ? "reader" : "writer") 
         << " thread " << _id << " released" << endl;
  }
      }
      catch (exception& e) {
  cerr << e.what() << endl;
  return 0;
      }
      return 0;
    }
  };
  threadmm::rwlock* rw::_lock = 0;
  

  class timed_rwlock 
  {
  private:
  public:
    int run() { 
      // Sync I/O
      // ios::sync_with_stdio(true);
      // cout.setf(ios::unitbuf);
      // cerr.setf(ios::unitbuf);

      rw::_lock = new threadmm::rwlock(::threadmm::reader);

      try {
  const int n = 5;
  rw** writers = new rw*[n];
  rw** readers = new rw*[n];
  
  for (int i = 0; i < n; i++) {
    writers[i] = new rw(false, i);
    writers[i]->run();
  }
  
  for (int i = 0; i < n; i++) {
    readers[i] = new rw(true, i);
    readers[i]->run();
  }
  
  for (int i = 0; i < n; i++) writers[i]->join();
  for (int i = 0; i < n; i++) readers[i]->join();
      }
      catch (exception& e) {
  cout << e.what() << endl;
  return 1;
      }
      return 0;
    }
  };
}

//_______________________________________________________________________
int main(int argc, char** argv)
{
  if (!example::options(argc, argv)) return 0;

  example::timed_rwlock exa;
  return exa.run();
}

//_______________________________________________________________________
// 
// EOF
//



Top of page
Last update Tue Nov 9 12:40:50 2004
Christian Holm
Created by DoxyGen 1.3.9.1