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.
- data/build/zeus-darwin-amd64 +0 -0
- data/build/zeus-linux-386 +0 -0
- data/build/zeus-linux-amd64 +0 -0
- data/ext/inotify-wrapper/inotify-wrapper.cpp +39 -9
- data/lib/zeus.rb +10 -18
- metadata +1 -1
data/build/zeus-darwin-amd64
CHANGED
Binary file
|
data/build/zeus-linux-386
CHANGED
Binary file
|
data/build/zeus-linux-amd64
CHANGED
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,
|
19
|
-
static map<
|
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(
|
26
|
+
void maybeAddFileToWatchList(string file)
|
24
27
|
{
|
25
28
|
if (_FileIsWatched[file]) return;
|
26
29
|
|
27
|
-
|
28
|
-
int
|
29
|
-
|
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
|
-
|
54
|
-
|
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
|
}
|
data/lib/zeus.rb
CHANGED
@@ -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(:
|
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
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
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
|