zeus 0.10.0.pre2 → 0.10.0.pre3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: