mirror of
https://github.com/ceph/ceph
synced 2024-12-24 12:24:19 +00:00
07ac5d3e74
git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@1068 29311d96-e01e-0410-9327-a35deaab8ce9
120 lines
2.2 KiB
C++
120 lines
2.2 KiB
C++
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
|
|
/*
|
|
* 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 __CONTEXT_H
|
|
#define __CONTEXT_H
|
|
|
|
#include "config.h"
|
|
|
|
#include <assert.h>
|
|
#include <list>
|
|
#include <set>
|
|
|
|
#include <iostream>
|
|
|
|
|
|
/*
|
|
* Context - abstract callback class
|
|
*/
|
|
class Context {
|
|
public:
|
|
virtual ~Context() {} // we want a virtual destructor!!!
|
|
virtual void finish(int r) = 0;
|
|
};
|
|
|
|
|
|
/*
|
|
* finish and destroy a list of Contexts
|
|
*/
|
|
inline void finish_contexts(std::list<Context*>& finished,
|
|
int result = 0)
|
|
{
|
|
using std::cout;
|
|
using std::endl;
|
|
|
|
if (finished.empty()) return;
|
|
|
|
dout(10) << finished.size() << " contexts to finish with " << result << endl;
|
|
for (std::list<Context*>::iterator it = finished.begin();
|
|
it != finished.end();
|
|
it++) {
|
|
Context *c = *it;
|
|
dout(10) << "---- " << c << endl;
|
|
c->finish(result);
|
|
delete c;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* C_Contexts - set of Contexts
|
|
*/
|
|
class C_Contexts : public Context {
|
|
std::list<Context*> clist;
|
|
|
|
public:
|
|
void add(Context* c) {
|
|
clist.push_back(c);
|
|
}
|
|
void take(std::list<Context*>& ls) {
|
|
clist.splice(clist.end(), ls);
|
|
}
|
|
void finish(int r) {
|
|
finish_contexts(clist, r);
|
|
}
|
|
};
|
|
|
|
|
|
/*
|
|
* C_Gather
|
|
*
|
|
* BUG: does not report errors.
|
|
*/
|
|
class C_Gather : public Context {
|
|
public:
|
|
class C_GatherSub : public Context {
|
|
C_Gather *gather;
|
|
int num;
|
|
public:
|
|
C_GatherSub(C_Gather *g, int n) : gather(g), num(n) {}
|
|
void finish(int r) {
|
|
gather->finish(num);
|
|
}
|
|
};
|
|
|
|
private:
|
|
Context *onfinish;
|
|
std::set<int> waitfor;
|
|
int num;
|
|
|
|
public:
|
|
C_Gather(Context *f) : onfinish(f), num(0) {}
|
|
|
|
void finish(int r) {
|
|
assert(waitfor.count(r));
|
|
waitfor.erase(r);
|
|
if (waitfor.empty()) {
|
|
onfinish->finish(0);
|
|
delete onfinish;
|
|
}
|
|
}
|
|
|
|
Context *new_sub() {
|
|
num++;
|
|
waitfor.insert(num);
|
|
return new C_GatherSub(this, num);
|
|
}
|
|
};
|
|
|
|
#endif
|