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 public:
00019
00020 OwnerBox(Owner *o, void (Owner::*fn)() ) :
00021 owner(o), callback(fn), data(0),
00022 numberUsers(0), openCount(0), closeCount(0) {};
00023
00024 ~OwnerBox(void) {
00025 if (numberUsers) {
00026 CkPrintf("OwnerBox::~OwnerBox() - still have boxes out there!\n");
00027 }
00028 }
00029
00030 void open(Data* d) {
00031 closeCount = openCount = numberUsers;
00032 data = d;
00033 if ( ! closeCount ) close();
00034 }
00035
00036 inline void close(void);
00037
00038 inline Box<Owner,Data> *checkOut(void);
00039
00040 inline void checkIn(Box<Owner,Data> * box);
00041
00042 int isOpen() {
00043 return (closeCount != numberUsers || openCount != numberUsers);
00044 }
00045
00046 private:
00047 Owner *owner;
00048 void (Owner::*callback)(void);
00049 Data* data;
00050 int numberUsers, openCount, closeCount;
00051 };
00052
00053 template <class Owner, class Data>
00054 inline Box<Owner,Data> *OwnerBox<Owner,Data>::checkOut(void) {
00055 if (closeCount != numberUsers || openCount != numberUsers) {
00056 CkPrintf("OwnerBox::checkOut() Tried to checkOut while in use\n");
00057 }
00058 ++numberUsers; ++closeCount; ++openCount;
00059 return (new Box<Owner,Data>(this));
00060 }
00061
00062 template <class Owner, class Data>
00063 inline void OwnerBox<Owner,Data>::checkIn(Box<Owner,Data> * box) {
00064 delete box;
00065 if (closeCount != numberUsers || openCount != numberUsers) {
00066 CkPrintf("OwnerBox::checkIn() Tried to checkIn while in use\n");
00067 }
00068 if ( ! numberUsers-- ) {
00069 CkPrintf("OwnerBox::checkIn() - no registrants remaining\n");
00070 numberUsers = 0;
00071 } else {
00072 closeCount--; openCount--;
00073 }
00074 }
00075
00076 template <class Owner, class Data>
00077 inline void OwnerBox<Owner,Data>::close(void) {
00078 if (!closeCount && !openCount) {
00079 data = 0; closeCount = openCount = numberUsers;
00080 (owner->*callback)();
00081 } else {
00082 CkPrintf("OwnerBox::close() - close called, but \
00083 closeCount %d openCount %d\n", closeCount, openCount);
00084 }
00085 }
00086
00087 #endif