summaryrefslogtreecommitdiff
path: root/src/osd/Watch.h
blob: 60810df7d67583f90355ed22640f6a411f17b4c5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- 
// vim: ts=8 sw=2 smarttab
/*
 * Ceph - scalable distributed file system
 *
 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
 *
 * This is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1, as published by the Free Software 
 * Foundation.  See file COPYING.
 * 
 */


#ifndef CEPH_WATCH_H
#define CEPH_WATCH_H

#include <map>

#include "common/config.h"

#include "OSD.h"

class MWatchNotify;

/* keeps track and accounts sessions, watchers and notifiers */
class Watch {
  uint64_t notif_id;

public:
  enum WatcherState {
    WATCHER_PENDING,
    WATCHER_NOTIFIED,
  };

  struct Notification {
    std::map<entity_name_t, WatcherState> watchers;
    entity_name_t name;
    uint64_t id;
    OSD::Session *session;
    uint64_t cookie;
    MWatchNotify *reply;
    Context *timeout;
    void *obc;
    pg_t pgid;
    bufferlist bl;

    void add_watcher(const entity_name_t& name, WatcherState state) {
      watchers[name] = state;
    }

    Notification(entity_name_t& n, OSD::Session *s, uint64_t c, bufferlist& b)
      : name(n), id(0), session(s), cookie(c), reply(0), timeout(0),
	obc(0), bl(b) { }
  };

  class C_NotifyTimeout : public Context {
    OSD *osd;
    Notification *notif;
  public:
    C_NotifyTimeout(OSD *_osd, Notification *_notif) : osd(_osd), notif(_notif) {}
    void finish(int r);
  };

  class C_WatchTimeout : public Context {
    OSD *osd;
    void *obc;
    void *pg;
    entity_name_t entity;
  public:
    utime_t expire;
    C_WatchTimeout(OSD *_osd, void *_obc, void *_pg,
		   entity_name_t _entity, utime_t _expire) :
      osd(_osd), obc(_obc), pg(_pg), entity(_entity), expire(_expire) {}
    void finish(int r);
  };

private:
  std::map<uint64_t, Notification *> notifs; /* notif_id to notifications */

public:
  Watch() : notif_id(0) {}

  void add_notification(Notification *notif) {
    notif->id = ++notif_id;
    notifs[notif->id] = notif;
  }
  Notification *get_notif(uint64_t id) {
    map<uint64_t, Notification *>::iterator iter = notifs.find(id);
    if (iter != notifs.end())
      return iter->second;
    return NULL;
  }
  void remove_notification(Notification *notif) {
    map<uint64_t, Notification *>::iterator iter = notifs.find(notif->id);
    if (iter != notifs.end())
      notifs.erase(iter);
  }

  bool ack_notification(entity_name_t& watcher, Notification *notif);
};



#endif