Merge branch 'refs/heads/t/aft_fixes'
authorAndre Noll <maan@tuebingen.mpg.de>
Mon, 25 Jun 2018 18:12:27 +0000 (20:12 +0200)
committerAndre Noll <maan@tuebingen.mpg.de>
Mon, 25 Jun 2018 18:17:56 +0000 (20:17 +0200)
Two fixes related to the audio file table.

Cooking for three weeks.

* refs/heads/t/aft_fixes:
  aft: Remember current audio file after SIGHUP.
  aft: Honor AUDIO_FILE_REMOVE events.
  server: Update status items on file renames.

1  2 
NEWS.md
aft.c

diff --combined NEWS.md
+++ b/NEWS.md
@@@ -2,28 -2,11 +2,32 @@@ NEW
  ====
  
  -------------------------------------------
 -0.6.2 (to be accounced) "elastic diversity"
 +0.6.2 (to be announced) "elastic diversity"
  -------------------------------------------
  
  - para_gui no longer waits up to one second to update the screen when
 -the geometry of the terminal changes.
 +  the geometry of the terminal changes.
 +- Minor documentation improvements.
 +- Improvements to the crypto subsystem.
 +- The server subcommand "task" has been deprecated. It still works,
 +  but prints nothing. It will be removed in the next major release.
 +- Server log output is now serialized, avoiding issues with partial
 +  lines.
 +- It is now possible to switch to a different afs database by changing
 +  the server configuration and sending SIGHUP to the server process.
 +- New server options: --listen--address, --http-listen-address and
 +  --dccp-listen-address. These options restrict the set of listening
 +  addresses of the TCP and DCCP sockets of the server process.
 +- The help commands of server, audiod, play now support --long. By default,
 +  the short help is shown.
 +- The code which merges the command line options with the config file
 +  options has been consolidated.
++- If the current audio file is renamed, the status items are now updated
++  accordingly.
++- After the server process received SIGHUP, changes to the current audio
++  file did not trigger an update of the status items. This has been fixed.
 +
 +Download: [tarball](./releases/paraslash-git.tar.xz)
  
  ----------------------------------------
  0.6.1 (2017-09-23) "segmented iteration"
diff --combined aft.c
--- 1/aft.c
--- 2/aft.c
+++ b/aft.c
@@@ -42,6 -42,7 +42,7 @@@ struct ls_data 
   */
  static struct osl_table *audio_file_table; /* NULL if table not open */
  static struct osl_row *current_aft_row; /* NULL if no audio file open */
+ static unsigned char current_hash[HASH_SIZE]; /* only used on sighup */
  
  static char *status_items;
  static char *parser_friendly_status_items;
@@@ -982,12 -983,6 +983,12 @@@ out
        WRITE_STATUS_ITEM(pb, SI_file_size, "%ld\n", statbuf.st_size / 1024);
  }
  
 +void free_status_items(void)
 +{
 +      freep(&status_items);
 +      freep(&parser_friendly_status_items);
 +}
 +
  static int make_status_items(void)
  {
        const struct lls_command *cmd = SERVER_CMD_CMD_PTR(LS);
        time_t current_time;
        int ret;
  
 +      free_status_items();
        if (!status_item_ls_data.path) /* no audio file open */
                return 0;
        ret = lls_parse(ARRAY_SIZE(argv), argv, cmd, &opts.lpr, NULL);
        if (ret < 0)
                goto out;
        make_inode_status_items(&pb);
 -      free(status_items);
        status_items = pb.buf;
  
        memset(&pb, 0, sizeof(pb));
        pb.max_size = shm_get_shmmax() - 1;
        pb.flags = PBF_SIZE_PREFIX;
        ret = print_list_item(&status_item_ls_data, &opts, &pb, current_time);
 -      if (ret < 0) {
 -              free(status_items);
 -              status_items = NULL;
 -              return ret;
 -      }
 +      if (ret < 0)
 +              goto out;
        make_inode_status_items(&pb);
 -      free(parser_friendly_status_items);
        parser_friendly_status_items = pb.buf;
        ret = 1;
  out:
 +      if (ret < 0)
 +              free_status_items();
        lls_free_parse_result(opts.lpr, cmd);
        return ret;
  }
@@@ -2479,28 -2476,30 +2480,30 @@@ int aft_check_attributes(uint64_t att_m
        return audio_file_loop(&acad, check_atts_of_audio_file);
  }
  
- /**
-  * Close the audio file table.
-  *
-  * \param flags Usual flags that are passed to osl_close_table().
-  *
-  * \sa \ref osl_close_table().
+ /*
+  * This sets audio_file_table to NULL, but leaves current_aft_row unmodified,
+  * though stale (pointing to unmapped memory). If the table is being closed
+  * because we received SIGHUP, the table will be reopened after the config file
+  * has been reloaded. We remember the hash of the current audio file here so
+  * that aft_open() can initialize current_aft_row by looking up the saved hash.
   */
  static void aft_close(void)
  {
+       int ret;
+       unsigned char *p;
+       if (current_aft_row) {
+               ret = get_hash_of_row(current_aft_row, &p);
+               if (ret < 0) {
+                       PARA_WARNING_LOG("hash lookup failure\n");
+                       current_aft_row = NULL;
+               } else
+                       memcpy(current_hash, p, HASH_SIZE);
+       }
        osl_close_table(audio_file_table, OSL_MARK_CLEAN);
        audio_file_table = NULL;
  }
  
- /**
-  * Open the audio file table.
-  *
-  * \param dir The database directory.
-  *
-  * \return Standard.
-  *
-  * \sa \ref osl_open_table().
-  */
  static int aft_open(const char *dir)
  {
        int ret;
                unsigned num;
                osl_get_num_rows(audio_file_table, &num);
                PARA_INFO_LOG("audio file table contains %u files\n", num);
-               return ret;
+               if (!current_aft_row) {
+                       PARA_DEBUG_LOG("no current aft row\n");
+                       return 1;
+               }
+               /* SIGHUP case, update current_aft_row */
+               ret = aft_get_row_of_hash(current_hash, &current_aft_row);
+               if (ret < 0) { /* not fatal */
+                       PARA_WARNING_LOG("current hash lookup failure: %s\n",
+                               para_strerror(-ret));
+                       current_aft_row = NULL;
+                       return 1;
+               }
+               PARA_NOTICE_LOG("current audio file hash lookup: success\n");
+               return 1;
        }
        PARA_NOTICE_LOG("failed to open audio file table\n");
        audio_file_table = NULL;
@@@ -2567,6 -2579,16 +2583,16 @@@ static int aft_event_handler(enum afs_e
                status_item_ls_data.afsi.last_played = old_last_played;
                make_status_items();
                return 1;
+       } case AUDIO_FILE_RENAME: {
+               char *path;
+               if (data != current_aft_row)
+                       return 0;
+               ret = get_audio_file_path_of_row(current_aft_row, &path);
+               if (ret < 0)
+                       return ret;
+               status_item_ls_data.path = path;
+               make_status_items();
+               return 1;
        } case AFHI_CHANGE: {
                if (data != current_aft_row)
                        return 0;
                        return ret;
                make_status_items();
                return 1;
+       } case AUDIO_FILE_REMOVE: {
+               if (data == current_aft_row)
+                       current_aft_row = NULL;
+               return 0;
        }
        case BLOB_RENAME:
        case BLOB_REMOVE: