zeus 0.10.0.pre2 → 0.10.0.pre3

Sign up to get free protection for your applications and to get access to all the features.
Binary file
Binary file
Binary file
@@ -9,24 +9,50 @@
9
9
  #include <sys/types.h>
10
10
  #include <sys/inotify.h>
11
11
 
12
+ #include <errno.h>
13
+
12
14
  #define EVENT_SIZE (sizeof (struct inotify_event))
13
15
  #define EVENT_BUF_LEN (1024 * (EVENT_SIZE + 16))
14
16
 
15
17
  using namespace std;
16
18
 
17
19
  static int _inotify_fd;
18
- static map<int, char*> _WatchedFiles;
19
- static map<char*, bool> _FileIsWatched;
20
+ static map<int, string> _WatchedFiles;
21
+ static map<string, bool> _FileIsWatched;
20
22
 
23
+ // static int inotifyFlags = IN_ATTRIB | IN_MODIFY | IN_MOVE_SELF | IN_DELETE_SELF;
21
24
  static int inotifyFlags = IN_ATTRIB | IN_MODIFY | IN_MOVE_SELF | IN_DELETE_SELF;
22
25
 
23
- void maybeAddFileToWatchList(char *file)
26
+ void maybeAddFileToWatchList(string file)
24
27
  {
25
28
  if (_FileIsWatched[file]) return;
26
29
 
27
- _FileIsWatched[file] = true;
28
- int wd = inotify_add_watch(_inotify_fd, file, inotifyFlags);
29
- _WatchedFiles[wd] = file;
30
+ int wd = inotify_add_watch(_inotify_fd, file.c_str(), inotifyFlags);
31
+ int attempts = 0;
32
+ // Files are momentarily inaccessible when they are rewritten. I couldn't
33
+ // find a good way to deal with this, so we poll 'deleted' files for 0.25s or so
34
+ // to see if they reappear.
35
+ while (wd == -1 && errno == ENOENT) {
36
+ usleep(10000);
37
+ wd = inotify_add_watch(_inotify_fd, file.c_str(), inotifyFlags);
38
+ if (attempts++ == 25) break; // try for at most about a quarter of a second
39
+ }
40
+ if (wd != -1) {
41
+ _WatchedFiles[wd] = file;
42
+ _FileIsWatched[file] = true;
43
+ }
44
+ }
45
+
46
+ // This essentially removes a file from the watchlist then
47
+ // immediately re-adds it. This is because when a file is rewritten,
48
+ // as so many editors love to do, the watchdescriptor no longer refers to
49
+ // the file, so re must re-watch the path.
50
+ void replaceFileInWatchList(int wd, string file)
51
+ {
52
+ _FileIsWatched.erase(file);
53
+ _WatchedFiles.erase(wd);
54
+ inotify_rm_watch(_inotify_fd, wd);
55
+ maybeAddFileToWatchList(file);
30
56
  }
31
57
 
32
58
  void handleStdin()
@@ -35,7 +61,7 @@ void handleStdin()
35
61
  if (fgets(line, sizeof(line), stdin) == NULL) return;
36
62
  line[strlen(line)-1] = 0;
37
63
 
38
- maybeAddFileToWatchList(line);
64
+ maybeAddFileToWatchList(string(line));
39
65
  }
40
66
 
41
67
  void handleInotify()
@@ -50,8 +76,12 @@ void handleInotify()
50
76
 
51
77
  while (i < length) {
52
78
  struct inotify_event *event = (struct inotify_event *) &buffer[i];
53
- printf("%s\n", _WatchedFiles[event->wd]);
54
- fflush(stdout);
79
+ string file = _WatchedFiles[event->wd];
80
+ if (file != "") {
81
+ printf("%s\n", file.c_str());
82
+ fflush(stdout);
83
+ replaceFileInWatchList(event->wd, file);
84
+ }
55
85
 
56
86
  i += EVENT_SIZE + event->len;
57
87
  }
@@ -44,17 +44,6 @@ module Zeus
44
44
  end
45
45
  end
46
46
 
47
- def handle_dead_children(sock)
48
- # TODO: It would be nice if it were impossible for this
49
- # to interfere with the identifer -> IO thing.
50
- loop do
51
- pid = Process.wait(-1, Process::WNOHANG)
52
- break if pid.nil?
53
- # sock.send("D:#{pid}")
54
- end
55
- rescue Errno::ECHILD
56
- end
57
-
58
47
  def go(identifier=:boot)
59
48
  identifier = identifier.to_sym
60
49
  $0 = "zeus slave: #{identifier}"
@@ -63,10 +52,12 @@ module Zeus
63
52
  master = UNIXSocket.for_fd(fd)
64
53
 
65
54
  # I need to give the master a way to talk to me exclusively
66
- local, remote = UNIXSocket.pair(:DGRAM)
55
+ local, remote = UNIXSocket.pair(:STREAM)
56
+
67
57
  master.send_io(remote)
68
58
 
69
59
  # Now I need to tell the master about my PID and ID
60
+ File.open("a.log","a") { |f| f.puts identifier}
70
61
  local.write "P:#{Process.pid}:#{identifier}\0"
71
62
 
72
63
  # Now we run the action and report its success/fail status to the master.
@@ -79,12 +70,13 @@ module Zeus
79
70
 
80
71
  # We are now 'connected'. From this point, we may receive requests to fork.
81
72
  loop do
82
- new_identifier = local.recv(1024)
83
- new_identifier.chomp!("\0")
84
- if new_identifier =~ /^S:/
85
- fork { plan.after_fork ; go(new_identifier.sub(/^S:/,'')) }
86
- else
87
- fork { plan.after_fork ; command(new_identifier.sub(/^C:/,''), local) }
73
+ messages = local.recv(1024)
74
+ messages.split("\0").each do |new_identifier|
75
+ if new_identifier =~ /^S:/
76
+ fork { plan.after_fork ; go(new_identifier.sub(/^S:/,'')) }
77
+ else
78
+ fork { plan.after_fork ; command(new_identifier.sub(/^C:/,''), local) }
79
+ end
88
80
  end
89
81
  end
90
82
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zeus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0.pre2
4
+ version: 0.10.0.pre3
5
5
  prerelease: 7
6
6
  platform: ruby
7
7
  authors: