Skip to content
This repository

Solaris directory watching resource leak / segfault bug fix #654

Closed
wants to merge 3 commits into from

2 participants

ashaffer Ben Noordhuis
ashaffer

Libuv doesn't properly clean up directory watches on solaris if they are in the PORT_LOADED state. I encountered this problem in node.js. To reproduce it, execute the following in a node console on solaris:

fs = require('fs');
h = fs.watch(<directory>);
h.close();

Then in a separate shell (without closing the node shell, of course) touch the folder you watched and you should get a seg fault.

Ben Noordhuis

The change itself LGTM but would it be possible to add a regression test?

ashaffer

Added.

Ben Noordhuis

Thanks. Can you sign the CLA? I believe you're not on the list yet.

ashaffer

Ok, signed.

Ben Noordhuis

Thanks Andrew, landed in 4997738. It'll be part of the next v0.8 node release.

Ben Noordhuis bnoordhuis closed this December 14, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
2  src/unix/sunos.c
@@ -376,7 +376,7 @@ int uv_fs_event_init(uv_loop_t* loop,
376 376
 
377 377
 
378 378
 void uv__fs_event_close(uv_fs_event_t* handle) {
379  
-  if (handle->fd == PORT_FIRED) {
  379
+  if (handle->fd == PORT_FIRED || handle->fd == PORT_LOADED) {
380 380
     port_dissociate(handle->loop->fs_fd, PORT_SOURCE_FILE, (uintptr_t)&handle->fo);
381 381
   }
382 382
   handle->fd = PORT_DELETED;
31  test/test-fs-event.c
@@ -296,6 +296,37 @@ TEST_IMPL(fs_event_watch_file_current_dir) {
296 296
   return 0;
297 297
 }
298 298
 
  299
+TEST_IMPL(fs_event_no_callback_after_close) {
  300
+  uv_loop_t* loop = uv_default_loop();
  301
+  int r;
  302
+
  303
+  /* Setup */
  304
+  remove("watch_dir/file1");
  305
+  remove("watch_dir/");
  306
+  create_dir(loop, "watch_dir");
  307
+  create_file(loop, "watch_dir/file1");
  308
+
  309
+  r = uv_fs_event_init(loop,
  310
+                       &fs_event,
  311
+                       "watch_dir/file1",
  312
+                       fs_event_cb_file,
  313
+  	       0);
  314
+  ASSERT(r != -1);
  315
+
  316
+  uv_close((uv_handle_t*)&fs_event, close_cb);
  317
+  touch_file(loop, "watch_dir/file1");
  318
+  uv_run(loop);
  319
+
  320
+  ASSERT(fs_event_cb_called == 0);
  321
+  ASSERT(close_cb_called == 1);
  322
+
  323
+  /* Cleanup */
  324
+  remove("watch_dir/file1");
  325
+  remove("watch_dir/");
  326
+
  327
+  MAKE_VALGRIND_HAPPY();
  328
+  return 0;
  329
+}
299 330
 
300 331
 TEST_IMPL(fs_event_no_callback_on_close) {
301 332
   uv_loop_t* loop = uv_default_loop();
2  test/test-list.h
@@ -176,6 +176,7 @@ TEST_DECLARE   (fs_event_watch_dir)
176 176
 TEST_DECLARE   (fs_event_watch_file)
177 177
 TEST_DECLARE   (fs_event_watch_file_twice)
178 178
 TEST_DECLARE   (fs_event_watch_file_current_dir)
  179
+TEST_DECLARE   (fs_event_no_callback_after_close)
179 180
 TEST_DECLARE   (fs_event_no_callback_on_close)
180 181
 TEST_DECLARE   (fs_event_immediate_close)
181 182
 TEST_DECLARE   (fs_event_close_with_pending_event)
@@ -446,6 +447,7 @@ TASK_LIST_START
446 447
   TEST_ENTRY  (fs_event_watch_file)
447 448
   TEST_ENTRY  (fs_event_watch_file_twice)
448 449
   TEST_ENTRY  (fs_event_watch_file_current_dir)
  450
+  TEST_ENTRY  (fs_event_no_callback_after_close)
449 451
   TEST_ENTRY  (fs_event_no_callback_on_close)
450 452
   TEST_ENTRY  (fs_event_immediate_close)
451 453
   TEST_ENTRY  (fs_event_close_with_pending_event)
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.