Skip to content
Browse files

fixed race condition between synchronous and asynchronous events

  • Loading branch information...
1 parent b16e03d commit c84ab1c917b3a31536def64a7cb3d53608ae7a1a @massemanet committed
Showing with 39 additions and 26 deletions.
  1. +13 −0 ChangeLog
  2. +14 −10 c_src/inotify_erlang.c
  3. +10 −14 src/inoteefy.erl
  4. +2 −2 src/inotify.erl
View
13 ChangeLog
@@ -0,0 +1,13 @@
+2010-02-01 Mats Cronqvist <masse@kreditor.se>
+
+ * c_src/inotify_erlang.c (note_remove):
+ driver will always return either a 2-tuple (synchronously) or a
+ 5-tuple (asynchronously)
+
+ * src/inotify.erl (test_start):
+ see above
+
+ * src/inoteefy.erl (talk_to_port):
+ fixed race condition between synchronous and asynchronous events
+
+
View
24 c_src/inotify_erlang.c
@@ -256,7 +256,7 @@ int note_read_send(int len, char *buf) {
event = (struct inotify_event *) &buf[idx];
/* encoding msg */
- /* Prepare the output buffer that will hold {event, Wd, Mask, Cookie, Name} */
+ /* Output buffer that will hold {event, Wd, Mask, Cookie, Name} */
if (ei_x_new_with_version(&result) ||
ei_x_encode_tuple_header(&result, 5)) return(-1);
@@ -326,7 +326,7 @@ int note_list(note_t *note, char *buf, int *index) {
note_entry_t *cur;
ei_x_buff result;
- /* Prepare the output buffer that will hold {ok, Result} or {error, Reason} */
+ /* Output buffer that will hold {ok, Result} or {error, Reason} */
if (ei_x_new_with_version(&result) ||
ei_x_encode_tuple_header(&result, 2)) return(-1);
ei_x_encode_atom(&result, "ok");
@@ -353,7 +353,7 @@ int note_open(note_t *note, char *buf, int *count) {
note_entry_t *newent;
ei_x_buff result;
- /* Prepare the output buffer that will hold {ok, Result} or {error, Reason} */
+ /* Output buffer that will hold {ok, Result} or {error, Reason} */
if (ei_x_new_with_version(&result) ||
ei_x_encode_tuple_header(&result, 2)) return(-1);
@@ -402,7 +402,7 @@ int note_close(note_t *note, char *buf, int *count) {
nextp = (*curpp)->next;
free(*curpp);
(*curpp) = nextp;
- /* Prepare the output buffer that will hold {ok, Result} or {error, Reason} */
+ /* Output buffer that will hold {ok, Result} or {error, Reason} */
if (ei_x_new_with_version(&result) ||
ei_x_encode_tuple_header(&result, 2)) return(-1);
if (ei_x_encode_atom(&result, "ok") ||
@@ -439,7 +439,7 @@ int note_add(note_t *note, char *buf, int *index) {
char pathname[512];
ei_x_buff result;
- /* Prepare the output buffer that will hold {ok, Result} or {error, Reason} */
+ /* Output buffer that will hold {ok, Result} or {error, Reason} */
if (ei_x_new_with_version(&result) ||
ei_x_encode_tuple_header(&result, 2)) return(-1);
@@ -448,7 +448,8 @@ int note_add(note_t *note, char *buf, int *index) {
mask = 0;
if (note_decode_mask(buf, index, &mask) < 0) {
- if (ei_x_encode_atom(&result, "error") || ei_x_encode_atom(&result, "bad_mask"))
+ if (ei_x_encode_atom(&result, "error") ||
+ ei_x_encode_atom(&result, "bad_mask"))
return(-1);
write_cmd(&result);
ei_x_free(&result);
@@ -459,7 +460,8 @@ int note_add(note_t *note, char *buf, int *index) {
return note_send_errno();
}
- if (ei_x_encode_atom(&result, "ok") || ei_x_encode_ulong(&result, wd)) return(-1);
+ if (ei_x_encode_atom(&result, "ok") ||
+ ei_x_encode_ulong(&result, wd)) return(-1);
write_cmd(&result);
ei_x_free(&result);
return(0);
@@ -470,7 +472,7 @@ int note_add(note_t *note, char *buf, int *index) {
* {ulong fd, ulong wd}
*
* returns
- * ok
+ * {ok,wd}
* {error, errno}
*/
int note_remove(note_t *note, char *buf, int *index) {
@@ -482,12 +484,14 @@ int note_remove(note_t *note, char *buf, int *index) {
if (inotify_rm_watch(fd, wd) < 0) {
- /* Prepare the output buffer that will hold {error, Reason} */
+ /* Output buffer that will hold {error, Reason} or {ok, Wd}*/
return note_send_errno();
}
if (ei_x_new_with_version(&result) ||
- ei_x_encode_atom(&result, "ok")) return(-1);
+ ei_x_encode_tuple_header(&result, 2)) return(-1);
+ if (ei_x_encode_atom(&result, "ok") ||
+ ei_x_encode_ulong(&result, wd)) return(-1);
write_cmd(&result);
ei_x_free(&result);
return(0);
View
24 src/inoteefy.erl
@@ -26,6 +26,7 @@ stop() ->
gen_server:cast(?MODULE,stop).
watch(File,Callback) ->
+ start(),
gen_server:cast(?MODULE,{watch,{File,Callback}}).
unwatch(File) ->
@@ -84,18 +85,13 @@ maybe_call_back({event,WD,Mask,Cookie,Name}) ->
end.
do_watch({File,CB},LD) ->
- case filelib:is_regular(File) of
- false->
- ?log([{no_such_file,File}]),LD;
- true ->
- try {ok,FD} = talk_to_port(LD#ld.port,{open}),
- {ok,WD} = talk_to_port(LD#ld.port,{add, FD, File, all}),
- put({file,File},{FD,WD,CB}),
- put({wd,WD},{File,FD,CB}),
- LD
- catch C:R ->
- ?log([{error_watching_file,File},{C,R}]),LD
- end
+ try {ok,FD} = talk_to_port(LD#ld.port,{open}),
+ {ok,WD} = talk_to_port(LD#ld.port,{add, FD, File, all}),
+ put({file,File},{FD,WD,CB}),
+ put({wd,WD},{File,FD,CB}),
+ LD
+ catch C:R ->
+ ?log([{error_watching_file,File},{C,R}]),LD
end.
do_unwatch(File,LD) ->
@@ -116,8 +112,8 @@ do_unwatch(File,LD) ->
talk_to_port(Port,Msg) ->
try
erlang:port_command(Port, term_to_binary(Msg)),
- receive {Port, {data, Data}} -> binary_to_term(Data)
- after 1000 -> throw(fd_open_timeout)
+ receive {Port, {data, D = <<131,104,2,_/binary>>}} -> binary_to_term(D)
+ after 1000 -> throw(talk_to_port_timeout)
end
catch _:R -> throw({talking_to_port_failed,{R,Port,Msg}})
end.
View
4 src/inotify.erl
@@ -32,9 +32,9 @@ test_start() ->
test_end(F,W) ->
io:format("remove~n"),
- ok = remove(F,W),
+ {ok,W} = remove(F,W),
io:format("close~n"),
- ok = close(F).
+ {ok,F} = close(F).
test() ->
%% this is the test file

0 comments on commit c84ab1c

Please sign in to comment.
Something went wrong with that request. Please try again.