00001
00007 #ifndef OWNERBOX_H
00008 #define OWNERBOX_H
00009
00010 #include "charm++.h"
00011
00012 template <class Owner, class Data> class Box;
00013
00014 template <class Owner, class Data> class OwnerBox {
00015
00016 friend class Box<Owner,Data>;
00017
00018 int bid, type;
00019
00020 public:
00021
00022 OwnerBox(Owner *o, void (Owner::*fn)() ) :
00023 bid(-1), type(-1),
00024 owner(o), callback(fn), data(0),
00025 numberUsers(0), openCount(0), closeCount(0) {};
00026
00027 OwnerBox(Owner *o, void (Owner::*fn)(), int id ,int tp) :
00028 bid(id), type(tp),
00029 owner(o), callback(fn), data(0),
00030 numberUsers(0), openCount(0), closeCount(0) {};
00031
00032
00033 ~OwnerBox(void) {
00034 if (numberUsers) {
00035 CkPrintf("OwnerBox::~OwnerBox() - still have boxes out there!\n");
00036 }
00037 }
00038
00039 void open(Data* d) {
00040 closeCount = openCount = numberUsers;
00041 data = d;
00042 if ( ! closeCount ) close();
00043 }
00044
00045 inline void close(void);
00046
00047 inline Box<Owner,Data> *checkOut(int id);
00048
00049 inline void checkIn(Box<Owner,Data> * box);
00050
00051 int isOpen() {
00052 return (closeCount != numberUsers || openCount != numberUsers);
00053 }
00054
00055
00056 void clientAdd();
00057 void clientRemove();
00058 Data* clientOpen(int count=1) {
00059 openCount -= count;
00060 return data;
00061 }
00062 void clientClose(int count=1) {
00063 if ( ! (closeCount -= count) ) close();
00064 }
00065
00066 private:
00067 Owner *owner;
00068 void (Owner::*callback)(void);
00069 Data* data;
00070 int numberUsers, openCount, closeCount;
00071 };
00072
00073 template <class Owner, class Data>
00074 inline void OwnerBox<Owner,Data>::clientAdd(void) {
00075 if (closeCount != numberUsers || openCount != numberUsers) {
00076 CkPrintf("OwnerBox::clientAdd() while in use\n");
00077 }
00078 ++numberUsers; ++closeCount; ++openCount;
00079 }
00080
00081 template <class Owner, class Data>
00082 inline Box<Owner,Data> *OwnerBox<Owner,Data>::checkOut(int id) {
00083 clientAdd();
00084 return (new Box<Owner,Data>(this,id));
00085 }
00086
00087 template <class Owner, class Data>
00088 inline void OwnerBox<Owner,Data>::clientRemove() {
00089 if (closeCount != numberUsers || openCount != numberUsers) {
00090 CkPrintf("OwnerBox::clientRemove() while in use\n");
00091 }
00092 if ( ! numberUsers-- ) {
00093 CkPrintf("OwnerBox::clientRemove() - no registrants remaining\n");
00094 numberUsers = 0;
00095 } else {
00096 closeCount--; openCount--;
00097 }
00098 }
00099
00100 template <class Owner, class Data>
00101 inline void OwnerBox<Owner,Data>::checkIn(Box<Owner,Data> * box) {
00102 delete box;
00103 clientRemove();
00104 }
00105
00106 template <class Owner, class Data>
00107 inline void OwnerBox<Owner,Data>::close(void) {
00108 if (!closeCount && !openCount) {
00109 data = 0; closeCount = openCount = numberUsers;
00110 (owner->*callback)();
00111 } else {
00112 CkPrintf("OwnerBox::close() - close called, but closeCount %d openCount %d\n", closeCount, openCount);
00113 }
00114 }
00115
00116 #endif