]> infiniteadaptability.org Git - seeder/commitdiff
...
authoralex <[email protected]>
Sat, 30 Apr 2022 01:25:07 +0000 (18:25 -0700)
committeralex <[email protected]>
Sat, 30 Apr 2022 01:25:07 +0000 (18:25 -0700)
12 files changed:
inc/add.h
inc/hashmap.h
inc/watch.h
src/add.c
src/hashmap.c
src/init.c
src/log.c
src/net/start.c
src/session.c
src/sighandler.c
src/watch.c
test/integration/test_utils.c

index f7a179cb56593ead7656d52a423af6d7d15fdc06..ceefb3242e2b6844845fc2fbc50519280a24b1c6 100644 (file)
--- a/inc/add.h
+++ b/inc/add.h
@@ -21,6 +21,7 @@ struct add_queue_entry {
 #define ADD_MESSAGE_ADDING_TORRENT "adding all files in %s to torrent named %s\n"
 #define ADD_MESSAGE_ADDED_FILE "added file: %s\n"
 #define ADD_MESSAGE_HASH_FILE_FAILED "failed to hash file: %s\n"
+#define ADD_MESSAGE_SHUTDOWN_FAILED "adding threads shutdown failed\n"
 
 #define ADD_QUEUE_INITIAL_SIZE 8
 
index d30d22f80cfe14e316f7f98d559f8ac79b5ebddf..c0217db96b1ad87ce15385e242f341b903217940 100644 (file)
@@ -10,7 +10,7 @@ struct hash_map {
 };
 
 void hashmap_clear(struct hash_map*);
-void *hashmap_find(struct hash_map*,const void*,size_t);
+void *hashmap_find(const struct hash_map*,const void*,size_t);
 void hashmap_free(struct hash_map*);
 int hashmap_init(struct hash_map**,size_t);
 int hashmap_insert(struct hash_map*,const void*,size_t,void*);
index 18b2aab09a943f4468672e0f5a39acb5cc99add0..7d636b4dcb511ca935a0abed341c4856aa2d289b 100644 (file)
@@ -10,6 +10,7 @@
 #define WATCH_MESSAGE_FAILED "failed to start watching\n"
 #define WATCH_MESSAGE_START "watching started: %s\n"
 #define WATCH_MESSAGE_START_FAILED "failed to start watching %s\n"
+#define WATCH_MESSAGE_SHUTDOWN_FAILED "failed to shutdown watching thread\n"
 
 int watch();
 
index 3afaacbfa59ada4a4f69f1279805116822080836..d0b590924879a1682f53fb6165d007eff314ae83 100644 (file)
--- a/src/add.c
+++ b/src/add.c
@@ -1,6 +1,7 @@
 #include<add.h>
 
 static pthread_mutex_t adding_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_t *adding_threads;
 
 static struct hash_map *add_queue;
 static size_t add_queue_index;
@@ -12,6 +13,7 @@ static int add_queue_entry_add_torrent(struct add_queue_entry*,struct torrent*);
 static void add_queue_entry_free(struct add_queue_entry*);
 static int add_queue_entry_init(struct add_queue_entry**);
 static int add_queue_resize();
+static void add_shutdown();
 static int add_to_queue(struct add_queue_entry*);
 static struct add_queue_entry *get_next();
 static int ftw_helper(const char*,const struct stat*,int);
@@ -19,6 +21,13 @@ static int ftw_helper(const char*,const struct stat*,int);
 int add() {
        struct torrent *p;
 
+       adding_threads = NULL;
+
+       if(0!=atexit(&add_shutdown)) {
+               perror("atexit");
+               return -1;
+       }
+
        if(hashmap_init(&add_queue,ADD_QUEUE_INITIAL_SIZE)<0) { return -1; }
 
        for(size_t i=0;i<session.torrents.infohashes->size;i++) {
@@ -30,7 +39,7 @@ int add() {
 
        add_queue_index = 0;
 
-       pthread_t *adding_threads = calloc(sizeof(pthread_t),global_options.worker_threads);
+       adding_threads = calloc(sizeof(pthread_t),global_options.worker_threads);
        for(size_t i=0;i<global_options.worker_threads;i++) {
                if(pthread_create(&(adding_threads[i]),NULL,&add_hash,NULL)!=0) {
                        perror("pthread_create");
@@ -38,12 +47,7 @@ int add() {
                }
        }
 
-       for(size_t i=0;i<global_options.worker_threads;i++) {
-               if(pthread_join(adding_threads[i],NULL)<0) { return -1; }
-       }
-
-       free(adding_threads);
-       hashmap_free(add_queue);
+       add_shutdown();
 
        return 1;
 }
@@ -181,6 +185,25 @@ static int add_queue_resize(size_t new_size) {
        return 1;
 }
 
+static void add_shutdown() {
+       log_info("shutting down adding threads\n"); // REMOVE
+       if(adding_threads!=NULL) {
+               for(size_t i=0;i<global_options.worker_threads;i++) {
+                       if(pthread_join(adding_threads[i],NULL)<0) {
+                               log_err(ADD_MESSAGE_SHUTDOWN_FAILED);
+                               return;
+                       }
+               }
+       
+               free(adding_threads);
+               hashmap_free(add_queue);
+
+               adding_threads = NULL;
+       }
+
+       log_info("shut down of add threads complete\n"); // REMOVE
+}
+
 static int add_to_queue(struct add_queue_entry *to_add) {
        struct add_queue_entry *p;
        int ret;
index 7dfdf06e6f5077ea952131f8b6441d09a8093da8..e223bb8eb02880884a70269a0f32e9e8c6218d39 100644 (file)
@@ -6,7 +6,7 @@ void hashmap_clear(struct hash_map *p) {
        }
 }
 
-void *hashmap_find(struct hash_map *p, const void *key, size_t key_size) {
+void *hashmap_find(const struct hash_map *p, const void *key, size_t key_size) {
        unsigned char hash[crypto_shorthash_BYTES];
        size_t index;
        
index 5dd2ce49b91bef1b7b6d075ed1841127a35bae8d..86e6a2ff6e7205c44bdaa8ee08a65e7331e639cd 100644 (file)
@@ -22,15 +22,21 @@ struct option long_options[] = {
 int init(int argc, char **argv) {
        int c;
 
+       /*
+        * Main Initialization:
+        * Order matters here
+        * 1. signal handler
+        * 2. defaults so base state is consistent
+        * 3. logging_setup() so debugging information in later steps
+        * 4. session_setup() so that watch directories can be added to session successfully.
+        */
        if(signal_handler()<0) { return -1; }
-       
+       if(defaults()<0) { return -1; }
+       if(logging_setup()<0) { return -1; }
        if(session_setup()<0) { return -1; }
 
-       if(defaults()<0) { return -1; }
        if(opt_load_from_env()<0) { return -1; }
 
-       if(logging_setup()<0) { return -1; }
-
        while(1) {
                int option_index = 0;
 
index 4572150d0f8464299a01f089b8a388ecc73b745f..7ce190a045eb87c8f92f413655806b410bcb2da7 100644 (file)
--- a/src/log.c
+++ b/src/log.c
@@ -166,9 +166,13 @@ void *log_poll(void *p) {
 static void log_shutdown() {
        int ret_cancel, ret_join;
        void *res;
+
+       log_info("shutting down logging thread\n");
                
        ret_cancel = pthread_cancel(logging_thread);
        ret_join = pthread_join(logging_thread,&res);
+       
+       log_info("shutting down logging thread 2\n");
 
        logging_thread = pthread_self();
        if((ret_cancel!=0)||(ret_join!=0)||(res!=PTHREAD_CANCELED)) {
@@ -191,5 +195,7 @@ int logging_setup() {
                return -1;
        }
 
+       log_info("logging started\n");
+
        return 1;
 }
index 8a26b4e9ccb6dada5fcbfbbc2468ec197542592c..0fc4140bb720dae459e1e1edfb6705752d3120d1 100644 (file)
@@ -9,6 +9,7 @@ static void net_stop();
 static void net_shutdown(void *p) {
        struct net_info *info = (struct net_info*)p;
 
+       close(info->epoll_fd);
        close(info->tcp_socket);
        close(info->udp_socket);
 
@@ -51,6 +52,7 @@ int net_start() {
 }
 
 static void net_stop() {
+       log_info("net thread stopping\n");
        for(size_t i=0;i<global_options.worker_threads;i++) {
                pthread_cancel(net_threads[i]);
        }
@@ -60,5 +62,6 @@ static void net_stop() {
                        log_err(NET_MESSAGE_SHUTDOWN_FAILED);
                }
        }
+       log_info("net thread stopped\n");
 }
 
index a9659b6f1d9f760fde7f4ac14ce730b5d15c44b6..9565c54d5ffb844d7e0ba40369381d2e28388748 100644 (file)
@@ -10,6 +10,8 @@ static int session_torrent_resize(struct hash_map**,size_t);
 static void session_clean() {
        struct torrent *p;
 
+       log_info("clearing session\n");
+
        for(size_t i=0;i<session.torrents.paths->size;i++) {
                p = session.torrents.paths->map[i];
                if(p!=NULL) { torrent_free(p); }
@@ -20,6 +22,8 @@ static void session_clean() {
 
        hashmap_clear(session.torrents.paths);
        hashmap_free(session.torrents.paths);
+       
+       log_info("session cleared\n");
 }
 
 struct torrent *session_find_torrent(uint8_t *infohash, size_t size) {
@@ -43,6 +47,8 @@ int session_setup() {
                return -1;
        }
 
+       log_info("session setup\n");
+
        return 1;
 }
 
index a46f90291f75ce0ab3d3b8b2a401cbdf7d30c9bc..793fa11a9843ee24e1f4e6705998e55bc3cedb18 100644 (file)
@@ -9,7 +9,7 @@ static void handle_interrupt() {
         * call exit explicitly will call functions registered
         * with atexit and do appropriate cleanup.
         */
-       exit(EXIT_SUCCESS);
+       exit(EXIT_FAILURE);
 }
 
 static void shutdown_success() {
index 142f7ec176d5c3e6f2ede940057772f1a1b127b6..71e0027bc190655ad4c5fd93d22a66b854fec32c 100644 (file)
@@ -1,12 +1,19 @@
 #include<watch.h>
 
+static int watch_fd;
 static pthread_t watching_thread;
 
+static void watch_shutdown();
 static void *watch_spawn(void*);
-static int watch_spawn_all(int,const char*,struct tree*);
-static void watch_poll(int);
+static int watch_spawn_all(const char*,struct tree*);
+static void watch_poll();
 
 int watch() {
+       if(0!=atexit(&watch_shutdown)) {
+               perror("atexit");
+               return -1;
+       }
+
        if(pthread_create(&watching_thread,NULL,&watch_spawn,NULL)!=0) {
                perror("pthread_create");
                return -1;
@@ -17,10 +24,9 @@ int watch() {
 
 static void *watch_spawn(void *unused) {
        struct torrent *p;
-       int fd;
        
-       fd = inotify_init();
-       if(fd<0) {
+       watch_fd = inotify_init();
+       if(watch_fd<0) {
                log_err(WATCH_MESSAGE_FAILED);
                perror("inotify_init");
                return NULL;
@@ -29,27 +35,26 @@ static void *watch_spawn(void *unused) {
        for(size_t i=0;i<session.torrents.infohashes->size;i++) {
                p = session.torrents.infohashes->map[i];
                if(p!=NULL) {
-                       if(watch_spawn_all(fd,p->root,p->tree)<0) { return NULL; }
+                       if(watch_spawn_all(p->root,p->tree)<0) { return NULL; }
                }
 
        }
 
-       watch_poll(fd);
+       watch_poll();
 
        return NULL;
 }
 
 #define WATCH_FLAGS IN_CLOSE_WRITE | IN_CREATE | IN_DELETE | IN_MODIFY | IN_MOVED_TO
 
-static int watch_spawn_all(int fd, const char *root, struct tree *tree) {
+static int watch_spawn_all(const char *root, struct tree *tree) {
        struct tree_entry *p;
 
-       if(fd<0) { return -1; }
        if(NULL==root) { return -1; }
        if(strlen(root)<=0) { return -1; }
        if(NULL==tree) { return -1; }
 
-       tree->watch_fd = inotify_add_watch(fd,root,WATCH_FLAGS);
+       tree->watch_fd = inotify_add_watch(watch_fd,root,WATCH_FLAGS);
        if(tree->watch_fd<0) {
                perror("inotify_add_watch");
                log_err(WATCH_MESSAGE_START_FAILED,root);
@@ -62,7 +67,7 @@ static int watch_spawn_all(int fd, const char *root, struct tree *tree) {
        while(p!=NULL) {
                if(p->children!=NULL) {
                        char *newroot = concat(root,p->name);
-                       if(watch_spawn_all(fd,newroot,p->children)<0) { return -1; }
+                       if(watch_spawn_all(newroot,p->children)<0) { return -1; }
                        free(newroot);
                }
                p = p->next;
@@ -71,14 +76,16 @@ static int watch_spawn_all(int fd, const char *root, struct tree *tree) {
        return 1;
 }
 
-static void watch_poll(int fd) {
+static void watch_poll() {
        /* see `man inotify` for explanation of alignment modifiers */
        char buf[4096] __attribute__ ((aligned(__alignof__(struct inotify_event))));
        const struct inotify_event *event;
        ssize_t len;
 
        for(;;) {
-               len = read(fd,buf,sizeof(buf));
+               pthread_testcancel();
+
+               len = read(watch_fd,buf,sizeof(buf));
                if(len<=0) {
                        perror("read");
                        break;
@@ -92,3 +99,12 @@ static void watch_poll(int fd) {
                }
        }
 }
+
+static void watch_shutdown() {
+       log_info("watch thread stopping\n");
+       if(0!=pthread_cancel(watching_thread)) {
+               log_err(WATCH_MESSAGE_SHUTDOWN_FAILED);
+       }
+       close(watch_fd);
+       log_info("watch thread stopped\n");
+}
index ed3cda2655f786704787d7643f09d9c4a5a173e7..373304db1462a403bd025327629a45060084ca46 100644 (file)
@@ -30,20 +30,27 @@ pid_t run(char *const opts[]) {
 void run_and_exit_successfully(char *const opts[]) {
        int status;
 
+       printf("running\n");
        pid_t child_pid = run(opts);
 
        // wait 5 seconds for startup   
+       printf("sleeping\n");
        sleep(5);
        
        // verify still running
+       printf("verify process running\n");
        assert(0==waitpid(child_pid,&status,WNOHANG));
 
        // SIGINT to shutdown
+       printf("send SIGINT\n");
        assert(0==kill(child_pid,SIGINT));
 
        // verify child process exited successfully
+       printf("waiting for child process to exit\n");
        assert(child_pid==waitpid(child_pid,&status,0));
+       printf("checking exit status\n");
        assert(WIFEXITED(status));
+       printf("success!\n");
 }
 
 void setup_env() {