fixed a bug where rsync/gcc broke it
diff --git a/aos/atom_code/starter/starter.cc b/aos/atom_code/starter/starter.cc
index dcff517..8f8a65d 100644
--- a/aos/atom_code/starter/starter.cc
+++ b/aos/atom_code/starter/starter.cc
@@ -11,6 +11,7 @@
#include <errno.h>
#include <string.h>
#include <sys/wait.h>
+#include <inttypes.h>
#include <map>
#include <functional>
@@ -89,18 +90,12 @@
: filename_(filename),
callback_(callback),
value_(value),
- check_filename_(check_filename) {
+ create_(create),
+ check_filename_(check_filename),
+ watch_(-1) {
init_once.Get();
- watch_ = inotify_add_watch(notify_fd, filename.c_str(),
- create ? IN_CREATE : (IN_ATTRIB | IN_MODIFY));
- if (watch_ == -1) {
- LOG(FATAL, "inotify_add_watch(%d, %s,"
- " %s ? IN_CREATE : (IN_ATTRIB | IN_MODIFY)) failed with %d: %s\n",
- notify_fd, filename.c_str(), create ? "true" : "false",
- errno, strerror(errno));
- }
- watchers[watch_] = this;
+ CreateWatch();
}
// Cleans up everything.
~FileWatch() {
@@ -119,14 +114,7 @@
notify_fd, watch_, errno, strerror(errno));
}
- if (watchers[watch_] != this) {
- LOG(WARNING, "watcher for %s (%p) didn't find itself in the map\n",
- filename_.c_str(), this);
- } else {
- watchers.erase(watch_);
- }
- LOG(DEBUG, "removed watch ID %d\n", watch_);
- watch_ = -1;
+ RemoveWatchFromMap();
}
private:
@@ -141,6 +129,34 @@
return NULL;
}
+ void RemoveWatchFromMap() {
+ if (watchers[watch_] != this) {
+ LOG(WARNING, "watcher for %s (%p) didn't find itself in the map\n",
+ filename_.c_str(), this);
+ } else {
+ watchers.erase(watch_);
+ }
+ LOG(DEBUG, "removed watch ID %d\n", watch_);
+ watch_ = -1;
+ }
+
+ void CreateWatch() {
+ assert(watch_ == -1);
+ watch_ = inotify_add_watch(notify_fd, filename_.c_str(),
+ create_ ? IN_CREATE : (IN_ATTRIB |
+ IN_MODIFY |
+ IN_DELETE_SELF |
+ IN_MOVE_SELF));
+ if (watch_ == -1) {
+ LOG(FATAL, "inotify_add_watch(%d, %s,"
+ " %s ? IN_CREATE : (IN_ATTRIB | IN_MODIFY)) failed with %d: %s\n",
+ notify_fd, filename_.c_str(), create_ ? "true" : "false",
+ errno, strerror(errno));
+ }
+ watchers[watch_] = this;
+ LOG(DEBUG, "watch for %s is %d\n", filename_.c_str(), watch_);
+ }
+
// This gets set up as the callback for EV_READ on the inotify file
// descriptor. It calls FileNotified on the appropriate instance.
static void INotifyReadable(int /*fd*/, short /*events*/, void *) {
@@ -171,8 +187,14 @@
if (watchers.count(notifyevt->wd) != 1) {
LOG(WARNING, "couldn't find whose watch ID %d is\n", notifyevt->wd);
} else {
- watchers[notifyevt->wd]->FileNotified((notifyevt->len > 0) ?
- notifyevt->name : NULL);
+ LOG(DEBUG, "mask=%"PRIu32"\n", notifyevt->mask);
+ // If it was something that means the file got deleted.
+ if (notifyevt->mask & (IN_MOVE_SELF | IN_DELETE_SELF | IN_IGNORED)) {
+ watchers[notifyevt->wd]->WatchDeleted();
+ } else {
+ watchers[notifyevt->wd]->FileNotified((notifyevt->len > 0) ?
+ notifyevt->name : NULL);
+ }
}
notifyevt = reinterpret_cast<inotify_event *>(
@@ -181,6 +203,14 @@
}
}
+ // INotifyReadable calls this method whenever the watch for our file gets
+ // removed somehow.
+ void WatchDeleted() {
+ LOG(DEBUG, "watch for %s deleted\n", filename_.c_str());
+ RemoveWatchFromMap();
+ CreateWatch();
+ }
+
// INotifyReadable calls this method whenever the watch for our file triggers.
void FileNotified(const char *filename) {
assert(watch_ != -1);
@@ -204,6 +234,7 @@
const std::string filename_;
const std::function<void(void *)> callback_;
void *const value_;
+ const bool create_;
std::string check_filename_;
// The watch descriptor or -1 if we don't have one any more.
@@ -332,7 +363,7 @@
if (restarts_.size() > kMaxRestartsNumber) {
time::Time oldest = restarts_.front();
restarts_.pop();
- if ((time::Time::Now() - oldest) > kMaxRestartsTime) {
+ if ((time::Time::Now() - oldest) <= kMaxRestartsTime) {
LOG(WARNING, "process %s getting restarted too often\n", name());
Timeout(kResumeWait, StaticStart, this);
return;
@@ -372,9 +403,13 @@
}
void FileModified() {
+ LOG(DEBUG, "file for %s modified\n", name());
struct timeval restart_time_timeval = kRestartWaitTime.ToTimeval();
// This will reset the timeout again if it hasn't run yet.
- evtimer_add(restart_timeout_.get(), &restart_time_timeval);
+ if (evtimer_add(restart_timeout_.get(), &restart_time_timeval) != 0) {
+ LOG(FATAL, "evtimer_add(%p, %p) failed\n",
+ restart_timeout_.get(), &restart_time_timeval);
+ }
}
static void StaticDoRestart(int, short, void *self) {
@@ -406,6 +441,8 @@
status->self = this;
status->old_pid = pid_;
Timeout(kProcessDieTime, StaticCheckDied, status);
+ } else {
+ LOG(WARNING, "%s restart attempted but not running\n", name());
}
}
@@ -478,6 +515,7 @@
LOG(FATAL, "forking to run \"%s\" failed with %d: %s\n",
binary_.c_str(), errno, strerror(errno));
}
+ LOG(DEBUG, "started \"%s\" successfully\n", binary_.c_str());
}
// A history of the times that this process has been restarted.
@@ -508,9 +546,9 @@
DISALLOW_COPY_AND_ASSIGN(Child);
};
const time::Time Child::kProcessDieTime = time::Time::InSeconds(0.5);
-const time::Time Child::kMaxRestartsTime = time::Time::InSeconds(2);
+const time::Time Child::kMaxRestartsTime = time::Time::InSeconds(4);
const time::Time Child::kResumeWait = time::Time::InSeconds(2);
-const time::Time Child::kRestartWaitTime = time::Time::InSeconds(1);
+const time::Time Child::kRestartWaitTime = time::Time::InSeconds(1.5);
// This is where all of the Child instances except core live.
std::vector<unique_ptr<Child>> children;