~mathiaz/+junk/ceph-new-pkg-review

« back to all changes in this revision

Viewing changes to src/common/Timer.h

  • Committer: Mathias Gug
  • Date: 2010-07-29 03:10:42 UTC
  • Revision ID: mathias.gug@canonical.com-20100729031042-n9n8kky962qb4onb
Import ceph_0.21-0ubuntu1 from https://launchpad.net/~clint-fewbar/+archive/ceph/+packages.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- 
 
2
// vim: ts=8 sw=2 smarttab
 
3
/*
 
4
 * Ceph - scalable distributed file system
 
5
 *
 
6
 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
 
7
 *
 
8
 * This is free software; you can redistribute it and/or
 
9
 * modify it under the terms of the GNU Lesser General Public
 
10
 * License version 2.1, as published by the Free Software 
 
11
 * Foundation.  See file COPYING.
 
12
 * 
 
13
 */
 
14
 
 
15
 
 
16
#ifndef CEPH_TIMER_H
 
17
#define CEPH_TIMER_H
 
18
 
 
19
#include "include/types.h"
 
20
#include "include/Context.h"
 
21
#include "Clock.h"
 
22
 
 
23
#include "Mutex.h"
 
24
#include "Cond.h"
 
25
#include "Thread.h"
 
26
 
 
27
#include <map>
 
28
#include <set>
 
29
using std::map;
 
30
using std::set;
 
31
 
 
32
#include <ext/hash_map>
 
33
using namespace __gnu_cxx;
 
34
 
 
35
 
 
36
/*** Timer
 
37
 * schedule callbacks
 
38
 */
 
39
 
 
40
//class Messenger;
 
41
 
 
42
 
 
43
namespace __gnu_cxx {
 
44
  template<> struct hash<Context*> {
 
45
    size_t operator()(const Context *p) const { 
 
46
      static hash<unsigned long> H;
 
47
      return H((unsigned long)p); 
 
48
    }
 
49
  };
 
50
}
 
51
 
 
52
 
 
53
class Timer {
 
54
 private:
 
55
  map< utime_t, set<Context*> >  scheduled;    // time -> (context ...)
 
56
  hash_map< Context*, utime_t >  event_times;  // event -> time
 
57
 
 
58
  bool get_next_due(utime_t &when);
 
59
 
 
60
  void register_timer();  // make sure i get a callback
 
61
  void cancel_timer();    // make sure i get a callback
 
62
 
 
63
  bool      thread_stop;
 
64
  Mutex     lock;
 
65
  bool      timed_sleep;
 
66
  bool      sleeping;
 
67
  Cond      sleep_cond;
 
68
  Cond      timeout_cond;
 
69
 
 
70
 public:
 
71
  void timer_entry();    // waiter thread (that wakes us up)
 
72
 
 
73
  class TimerThread : public Thread {
 
74
    Timer *t;
 
75
  public:
 
76
    void *entry() {
 
77
      t->timer_entry();
 
78
      return 0;
 
79
    }
 
80
    TimerThread(Timer *_t) : t(_t) {}
 
81
  } timer_thread;
 
82
 
 
83
 
 
84
  int num_event;
 
85
 
 
86
 
 
87
 public:
 
88
  Timer() :
 
89
    thread_stop(false),
 
90
    lock("Timer::lock"),
 
91
    timed_sleep(false),
 
92
    sleeping(false),
 
93
    timer_thread(this),
 
94
    num_event(0)
 
95
  { 
 
96
  }
 
97
  virtual ~Timer() {
 
98
    // stop.
 
99
    cancel_timer();
 
100
 
 
101
    // scheduled
 
102
    for (map< utime_t, set<Context*> >::iterator it = scheduled.begin();
 
103
         it != scheduled.end();
 
104
         it++) {
 
105
      for (set<Context*>::iterator sit = it->second.begin();
 
106
           sit != it->second.end();
 
107
           sit++)
 
108
        delete *sit;
 
109
    }
 
110
    scheduled.clear();
 
111
  }
 
112
  
 
113
  void init() {
 
114
    register_timer();
 
115
  }
 
116
  void shutdown() {
 
117
    cancel_timer();
 
118
    cancel_all_events();
 
119
  }
 
120
 
 
121
  // schedule events
 
122
  virtual void add_event_after(double seconds,
 
123
                       Context *callback);
 
124
  virtual void add_event_at(utime_t when,
 
125
                    Context *callback);
 
126
  virtual bool cancel_event(Context *callback);
 
127
  virtual void cancel_all_events();
 
128
 
 
129
  // execute pending events
 
130
  void execute_pending();
 
131
 
 
132
};
 
133
 
 
134
 
 
135
/*
 
136
 * SafeTimer is a wrapper around the a Timer that protects event
 
137
 * execution with an existing mutex.  It provides for, among other
 
138
 * things, reliable event cancellation on class destruction.  The
 
139
 * caller just needs to cancel each event (or cancel_all()), and then
 
140
 * call join() to ensure any concurrently exectuting events (in other
 
141
 * threads) get flushed.
 
142
 */
 
143
class SafeTimer : public Timer {
 
144
  Mutex&        lock;
 
145
  Cond          cond;
 
146
  map<Context*,Context*> scheduled;  // actual -> wrapper
 
147
  map<Context*,Context*> canceled;
 
148
  
 
149
  class EventWrapper : public Context {
 
150
    SafeTimer *timer;
 
151
    Context *actual;
 
152
  public:
 
153
    EventWrapper(SafeTimer *st, Context *c) : timer(st), 
 
154
                                              actual(c) {}
 
155
    void finish(int r);
 
156
  };
 
157
 
 
158
public:
 
159
  SafeTimer(Mutex& l) : lock(l) { }
 
160
  ~SafeTimer();
 
161
 
 
162
  void add_event_after(double seconds, Context *c);
 
163
  void add_event_at(utime_t when, Context *c);
 
164
  bool cancel_event(Context *c);
 
165
  void cancel_all();
 
166
  void join();
 
167
 
 
168
  int get_num_scheduled() { return scheduled.size(); }
 
169
  int get_num_canceled() { return canceled.size(); }
 
170
};
 
171
 
 
172
 
 
173
 
 
174
 
 
175
#endif