Alexandre Julliard : server: Use the standard file descriptor signal mechanism for directory changes.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Apr 4 15:40:07 CDT 2007


Module: wine
Branch: master
Commit: a8675531461c21aa8ae0dd43ff1dc403dbbedea5
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=a8675531461c21aa8ae0dd43ff1dc403dbbedea5

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Apr  4 19:54:33 2007 +0200

server: Use the standard file descriptor signal mechanism for directory changes.

---

 dlls/ntdll/directory.c |    9 --------
 server/change.c        |   50 +++--------------------------------------------
 2 files changed, 4 insertions(+), 55 deletions(-)

diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c
index 50aaa27..ef6802b 100644
--- a/dlls/ntdll/directory.c
+++ b/dlls/ntdll/directory.c
@@ -2178,15 +2178,6 @@ static void WINAPI read_changes_apc( void *user, PIO_STATUS_BLOCK iosb, ULONG st
 
     TRACE("%p %p %08x\n", info, iosb, status);
 
-    /*
-     * FIXME: race me!
-     *
-     * hEvent/hDir is set before the output buffer and iosb is updated.
-     * Since the thread that called NtNotifyChangeDirectoryFile is usually
-     * waiting, we'll be safe since we're called in that thread's context.
-     * If a different thread is waiting on our hEvent/hDir we're going to be
-     * in trouble...
-     */
     SERVER_START_REQ( read_change )
     {
         req->handle = info->FileHandle;
diff --git a/server/change.c b/server/change.c
index 30b7346..33034da 100644
--- a/server/change.c
+++ b/server/change.c
@@ -147,11 +147,9 @@ struct dir
     struct object  obj;      /* object header */
     struct fd     *fd;       /* file descriptor to the directory */
     struct list    entry;    /* entry in global change notifications list */
-    struct event  *event;
     unsigned int   filter;   /* notification filter */
     int            notified; /* SIGIO counter */
     int            want_data; /* return change data */
-    long           signaled; /* the file changed */
     int            subtree;  /* do we want to watch subdirectories? */
     struct list    change_records;   /* data for the change */
     struct list    in_entry; /* entry in the inode dirs list */
@@ -162,7 +160,6 @@ static struct fd *dir_get_fd( struct object *obj );
 static unsigned int dir_map_access( struct object *obj, unsigned int access );
 static void dir_dump( struct object *obj, int verbose );
 static void dir_destroy( struct object *obj );
-static int dir_signaled( struct object *obj, struct thread *thread );
 
 static const struct object_ops dir_ops =
 {
@@ -170,7 +167,7 @@ static const struct object_ops dir_ops =
     dir_dump,                 /* dump */
     add_queue,                /* add_queue */
     remove_queue,             /* remove_queue */
-    dir_signaled,             /* signaled */
+    default_fd_signaled,      /* signaled */
     no_satisfied,             /* satisfied */
     no_signal,                /* signal */
     dir_get_fd,               /* get_fd */
@@ -254,15 +251,7 @@ static void dir_dump( struct object *obj, int verbose )
 {
     struct dir *dir = (struct dir *)obj;
     assert( obj->ops == &dir_ops );
-    fprintf( stderr, "Dirfile fd=%p event=%p filter=%08x\n",
-             dir->fd, dir->event, dir->filter );
-}
-
-static int dir_signaled( struct object *obj, struct thread *thread )
-{
-    struct dir *dir = (struct dir *)obj;
-    assert (obj->ops == &dir_ops);
-    return (dir->event == NULL) && dir->signaled;
+    fprintf( stderr, "Dirfile fd=%p filter=%08x\n", dir->fd, dir->filter );
 }
 
 /* enter here directly from SIGIO signal handler */
@@ -279,11 +268,6 @@ void do_change_notify( int unix_fd )
     }
 }
 
-static void dir_signal_changed( struct dir *dir )
-{
-    if (!dir->event) wake_up( &dir->obj, 0 );
-}
-
 /* SIGIO callback, called synchronously with the poll loop */
 void sigio_callback(void)
 {
@@ -291,13 +275,8 @@ void sigio_callback(void)
 
     LIST_FOR_EACH_ENTRY( dir, &change_list, struct dir, entry )
     {
-        long count = interlocked_xchg( &dir->notified, 0 );
-        if (count)
-        {
-            dir->signaled += count;
-            if (dir->signaled == count)  /* was it 0? */
-                dir_signal_changed( dir );
-        }
+        if (interlocked_xchg( &dir->notified, 0 ))
+            fd_async_wake_up( dir->fd, ASYNC_TYPE_WAIT, STATUS_NOTIFY_ENUM_DIR );
     }
 }
 
@@ -342,7 +321,6 @@ static void dir_destroy( struct object *obj )
 
     while ((record = get_first_change_record( dir ))) free( record );
 
-    if (dir->event) release_object( dir->event );
     release_object( dir->fd );
 
     if (inotify_fd && list_empty( &change_list ))
@@ -1038,10 +1016,8 @@ struct object *create_dir_obj( struct fd *fd )
         return NULL;
 
     list_init( &dir->change_records );
-    dir->event = NULL;
     dir->filter = 0;
     dir->notified = 0;
-    dir->signaled = 0;
     dir->want_data = 0;
     dir->inode = NULL;
     grab_object( fd );
@@ -1056,7 +1032,6 @@ struct object *create_dir_obj( struct fd *fd )
 /* enable change notifications for a directory */
 DECL_HANDLER(read_directory_changes)
 {
-    struct event *event = NULL;
     struct dir *dir;
     struct async *async;
 
@@ -1070,15 +1045,6 @@ DECL_HANDLER(read_directory_changes)
     if (!dir)
         return;
 
-    /* possibly send changes through an event flag */
-    if (req->async.event &&
-        !(event = get_event_obj( current->process, req->async.event, EVENT_MODIFY_STATE )))
-        goto end;
-
-    /* discard the current data, and move onto the next event */
-    if (dir->event) release_object( dir->event );
-    dir->event = event;
-
     /* requests don't timeout */
     if (!(async = fd_queue_async( dir->fd, &req->async, ASYNC_TYPE_WAIT, 0 ))) goto end;
 
@@ -1092,10 +1058,6 @@ DECL_HANDLER(read_directory_changes)
         dir->want_data = req->want_data;
     }
 
-    /* remove any notifications */
-    if (dir->signaled>0)
-        dir->signaled--;
-
     /* if there's already a change in the queue, send it */
     if (!list_empty( &dir->change_records ))
         fd_async_wake_up( dir->fd, ASYNC_TYPE_WAIT, STATUS_ALERTED );
@@ -1129,9 +1091,5 @@ DECL_HANDLER(read_change)
     else
         set_error( STATUS_NO_DATA_DETECTED );
 
-    /* now signal it */
-    dir->signaled++;
-    dir_signal_changed( dir );
-
     release_object( dir );
 }




More information about the wine-cvs mailing list