00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "Registration.h"
00019 #include "bundling/Bundle.h"
00020 #include "bundling/BundleDaemon.h"
00021 #include "bundling/BundleList.h"
00022 #include "storage/GlobalStore.h"
00023
00024 namespace dtn {
00025
00026
00027 const char*
00028 Registration::failure_action_toa(failure_action_t action)
00029 {
00030 switch(action) {
00031 case DROP: return "DROP";
00032 case DEFER: return "DEFER";
00033 case EXEC: return "EXEC";
00034 }
00035
00036 return "__INVALID__";
00037 }
00038
00039
00040 Registration::Registration(u_int32_t regid,
00041 const EndpointIDPattern& endpoint,
00042 int action,
00043 u_int32_t expiration,
00044 const std::string& script)
00045
00046 : Logger("Registration", "/dtn/registration/%d", regid),
00047 regid_(regid),
00048 endpoint_(endpoint),
00049 failure_action_(action),
00050 script_(script),
00051 expiration_(expiration),
00052 expiration_timer_(NULL),
00053 active_(false),
00054 expired_(false)
00055 {
00056 struct timeval now;
00057 ::gettimeofday(&now, 0);
00058 creation_time_ = now.tv_sec;
00059
00060 init_expiration_timer();
00061 }
00062
00063
00064 Registration::Registration(const oasys::Builder&)
00065 : Logger("Registration", "/dtn/registration"),
00066 regid_(0),
00067 endpoint_(),
00068 failure_action_(DEFER),
00069 script_(),
00070 expiration_(0),
00071 creation_time_(0),
00072 expiration_timer_(NULL),
00073 active_(false),
00074 expired_(false)
00075 {
00076 }
00077
00078
00079 Registration::~Registration()
00080 {
00081 cleanup_expiration_timer();
00082 }
00083
00084
00085 void
00086 Registration::force_expire()
00087 {
00088 ASSERT(active_);
00089
00090 cleanup_expiration_timer();
00091 set_expired(true);
00092 }
00093
00094
00095 void
00096 Registration::cleanup_expiration_timer()
00097 {
00098 if (expiration_timer_) {
00099
00100
00101
00102
00103 bool pending = expiration_timer_->cancel();
00104
00105 if (! pending) {
00106 ASSERT(expired_);
00107 delete expiration_timer_;
00108 }
00109
00110 expiration_timer_ = NULL;
00111 }
00112 }
00113
00114
00115 void
00116 Registration::serialize(oasys::SerializeAction* a)
00117 {
00118 a->process("endpoint", &endpoint_);
00119 a->process("regid", ®id_);
00120 a->process("action", &failure_action_);
00121 a->process("script", &script_);
00122 a->process("creation_time", &creation_time_);
00123 a->process("expiration", &expiration_);
00124
00125
00126 if (a->action_code() == oasys::Serialize::UNMARSHAL) {
00127 init_expiration_timer();
00128 }
00129
00130 logpathf("/dtn/registration/%d", regid_);
00131 }
00132
00133
00134 void
00135 Registration::init_expiration_timer()
00136 {
00137 if (expiration_ != 0) {
00138 struct timeval when, now;
00139 when.tv_sec = creation_time_ + expiration_;
00140 when.tv_usec = 0;
00141
00142 ::gettimeofday(&now, 0);
00143
00144 long int in_how_long = TIMEVAL_DIFF_MSEC(when, now);
00145 if (in_how_long < 0) {
00146 log_warn("scheduling IMMEDIATE expiration for registration id %d: "
00147 "[creation_time %u, expiration %u, now %u]",
00148 regid_, creation_time_, expiration_, (u_int)now.tv_sec);
00149 } else {
00150 log_debug("scheduling expiration for registration id %d at %u.%u "
00151 "(in %ld seconds): ", regid_,
00152 (u_int)when.tv_sec, (u_int)when.tv_usec,
00153 in_how_long / 1000);
00154 }
00155
00156 expiration_timer_ = new ExpirationTimer(this);
00157 expiration_timer_->schedule_at(&when);
00158
00159 } else {
00160 set_expired(true);
00161 }
00162 }
00163
00164
00165 void
00166 Registration::ExpirationTimer::timeout(const struct timeval& now)
00167 {
00168 (void)now;
00169
00170 reg_->set_expired(true);
00171
00172 if (! reg_->active()) {
00173 BundleDaemon::post(new RegistrationExpiredEvent(reg_->regid()));
00174 }
00175 }
00176
00177 }