Exit parent fsctl thread only after joining all of its child threads.
authorshort <>
Fri, 22 Aug 2003 09:00:21 +0000 (09:00 +0000)
committershort <>
Fri, 22 Aug 2003 09:00:21 +0000 (09:00 +0000)
 - Prevents atexit handlers execution before finishing all child operations.

lufsd/fsctl.c
lufsd/fsctl.h

index e9301a1..5f9b832 100644 (file)
 
 char sock_name[MAX_LEN];
 
+static int usr1Handler_hit=0;
 static void
 usr1Handler(int sig){
 
-    TRACE("unmounting filesystem...");
-    TRACE("socket name: %s", sock_name);
-    unlink(sock_name);
-
-    exit(0);
+    TRACE("usr1Handler...");
+    usr1Handler_hit=1;
 }
 
 static void
@@ -83,20 +81,21 @@ thread_launcher(void *params){
 
     TRACE("thread created");
     
-    free(p);
-
     if(fs) {
        handle_fs(fs, sock, ppid);
-
-       if(fs->fs_ops->umount)
-           fs->fs_ops->umount(fs->fs_context);
-       fs->fs_ops->free(fs->fs_context);
-
-       free(fs);
     }else{
        WARN("could not instantiate filesystem (out of mem?) !");
     }
 
+    if(fs->fs_ops->umount){
+       TRACE("unmounting filesystem...");
+       fs->fs_ops->umount(fs->fs_context);
+    }
+    TRACE("freeing filesystem...");
+    fs->fs_ops->free(fs->fs_context);
+
+    free(fs);
+
     close(sock);
     TRACE("thread exiting...");
 
@@ -398,11 +397,11 @@ lu_fsctl_mount(struct fs_ctl *ctl){
 
 void
 lu_fsctl_run(struct fs_ctl *ctl, int ssock, char *sn){
-    pthread_t th_id;
     socklen_t len;
     struct sockaddr_un addr;
     int sock;
-    struct thread_info *info;
+    struct thread_info *info, *info_list=NULL;
+    struct sigaction sigaction_struct;
 
     if(strlen(sn) >= MAX_LEN){
        WARN("socket name too long!");
@@ -411,13 +410,20 @@ lu_fsctl_run(struct fs_ctl *ctl, int ssock, char *sn){
     
     strcpy(sock_name, sn);
 
+#if 0  /* signal(2) will not abort accept(2) below. */
     signal(SIGUSR1, usr1Handler);
+#else
+    memset(&sigaction_struct, 0, sizeof(sigaction_struct));
+    sigaction_struct.sa_handler = usr1Handler;
+    sigaction_struct.sa_flags = 0;     /* !SA_RESTART */
+    sigaction(SIGUSR1, &sigaction_struct, NULL);
+#endif
 
     signal(SIGPIPE, sig_handler);
     signal(SIGTERM, sig_handler);
     signal(SIGINT, sig_handler);
     
-    while(1){
+    while(!usr1Handler_hit){
        len = sizeof(struct sockaddr_un);
 
        if((sock = accept(ssock, (struct sockaddr*)&addr, &len)) < 0){
@@ -438,8 +444,9 @@ lu_fsctl_run(struct fs_ctl *ctl, int ssock, char *sn){
 
                info->sock = sock;
                info->ppid = getpid();
-               if(!pthread_create(&th_id, NULL, &thread_launcher, (void*)info)){
-                   pthread_detach(th_id);
+               if(!pthread_create(&info->th_id, NULL, &thread_launcher, (void*)info)){
+                   info->next = info_list;
+                   info_list= info;
                }else{
                    WARN("could not create thread!");
                    free(info);
@@ -450,6 +457,27 @@ lu_fsctl_run(struct fs_ctl *ctl, int ssock, char *sn){
        }
     }
 
+    TRACE("joining threads...");
+    while ((info = info_list)){
+       info_list = info->next;
+       if (pthread_join(info->th_id, NULL))
+           WARN("could not join thread!");
+       free(info);
+    }
+    if (ctl->fs_available){
+       struct file_system *fs = ctl->fs_available;
+
+       if(fs->fs_ops->umount){
+           TRACE("unmounting filesystem...");
+           fs->fs_ops->umount(fs->fs_context);
+       }
+       TRACE("freeing filesystem...");
+       fs->fs_ops->free(fs->fs_context);
+
+       free(fs);
+    }
+    TRACE("socket name: %s", sock_name);
+    unlink(sock_name);
 }
 
 struct fs_ctl*
index 0bfc909..8e121ae 100644 (file)
@@ -27,9 +27,11 @@ struct fs_operations;
 struct file_system;
 
 struct thread_info{
+    struct thread_info *next;
     struct file_system *fs;
     int                        sock;
     pid_t              ppid;
+    pthread_t          th_id;
 };
 
 struct fs_ctl{