]> git.tuebingen.mpg.de Git - paraslash.git/commitdiff
Merge branch 'master' into next
authorAndre Noll <maan@systemlinux.org>
Mon, 14 Sep 2009 08:09:38 +0000 (10:09 +0200)
committerAndre Noll <maan@systemlinux.org>
Mon, 14 Sep 2009 08:09:38 +0000 (10:09 +0200)
1  2 
fd.c
vss.c

diff --combined fd.c
index 3dc490cde1056db92e94108cb7ad3c97131d32d5,31eb638826f93206e7d36814b7d4cd8b8988a898..0fb796025945b2c33e59c6c8508d370626ac0c02
--- 1/fd.c
--- 2/fd.c
+++ b/fd.c
@@@ -6,7 -6,6 +6,7 @@@
  
  /** \file fd.c Helper functions for file descriptor handling. */
  
 +#include <regex.h>
  #include <sys/types.h>
  #include <dirent.h>
  #include <sys/mman.h>
@@@ -15,7 -14,6 +15,7 @@@
  
  #include "para.h"
  #include "error.h"
 +#include "string.h"
  
  /**
   * Write a buffer to a file descriptor, re-write on short writes.
@@@ -116,10 -114,11 +116,10 @@@ int file_exists(const char *fn
  int para_select(int n, fd_set *readfds, fd_set *writefds,
                struct timeval *timeout_tv)
  {
 -      int ret, err;
 -      do {
 +      int ret;
 +      do
                ret = select(n, readfds, writefds, NULL, timeout_tv);
 -              err = errno;
 -      } while (ret < 0 && err == EINTR);
 +      while (ret < 0 && errno == EINTR);
        if (ret < 0)
                return -ERRNO_TO_PARA_ERROR(errno);
        return ret;
@@@ -421,7 -420,7 +421,7 @@@ out
   * \param start The start address of the memory mapping.
   * \param length The size of the mapping.
   *
-  * \return Positive on success, \p -E_MUNMAP on errors.
+  * \return Standard.
   *
   * \sa munmap(2), mmap_full_file().
   */
@@@ -447,14 -446,18 +447,14 @@@ int para_munmap(void *start, size_t len
  
  int write_ok(int fd)
  {
 -      struct timeval tv = {0, 0};
 +      struct timeval tv;
        fd_set wfds;
 -      int ret;
 -again:
 +
        FD_ZERO(&wfds);
        FD_SET(fd, &wfds);
        tv.tv_sec = 0;
        tv.tv_usec = 0;
 -      ret = select(fd + 1, NULL, &wfds, NULL, &tv);
 -      if (ret < 0 && errno == EINTR)
 -              goto again;
 -      return ret;
 +      return para_select(fd + 1, NULL, &wfds, &tv);
  }
  
  /**
@@@ -477,65 -480,3 +477,65 @@@ void valid_fd_012(void
                }
        }
  }
 +
 +/**
 + * Traverse the given directory recursively.
 + *
 + * \param dirname The directory to traverse.
 + * \param func The function to call for each entry.
 + * \param private_data Pointer to an arbitrary data structure.
 + *
 + * For each regular file under \a dirname, the supplied function \a func is
 + * called.  The full path of the regular file and the \a private_data pointer
 + * are passed to \a func. Directories for which the calling process has no
 + * permissions to change to are silently ignored.
 + *
 + * \return Standard.
 + */
 +int for_each_file_in_dir(const char *dirname,
 +              int (*func)(const char *, void *), void *private_data)
 +{
 +      DIR *dir;
 +      struct dirent *entry;
 +      int cwd_fd, ret2, ret = para_opendir(dirname, &dir, &cwd_fd);
 +
 +      if (ret < 0)
 +              return ret == -ERRNO_TO_PARA_ERROR(EACCES)? 1 : ret;
 +      /* scan cwd recursively */
 +      while ((entry = readdir(dir))) {
 +              mode_t m;
 +              char *tmp;
 +              struct stat s;
 +
 +              if (!strcmp(entry->d_name, "."))
 +                      continue;
 +              if (!strcmp(entry->d_name, ".."))
 +                      continue;
 +              if (lstat(entry->d_name, &s) == -1)
 +                      continue;
 +              m = s.st_mode;
 +              if (!S_ISREG(m) && !S_ISDIR(m))
 +                      continue;
 +              tmp = make_message("%s/%s", dirname, entry->d_name);
 +              if (!S_ISDIR(m)) {
 +                      ret = func(tmp, private_data);
 +                      free(tmp);
 +                      if (ret < 0)
 +                              goto out;
 +                      continue;
 +              }
 +              /* directory */
 +              ret = for_each_file_in_dir(tmp, func, private_data);
 +              free(tmp);
 +              if (ret < 0)
 +                      goto out;
 +      }
 +      ret = 1;
 +out:
 +      closedir(dir);
 +      ret2 = para_fchdir(cwd_fd);
 +      if (ret2 < 0 && ret >= 0)
 +              ret = ret2;
 +      close(cwd_fd);
 +      return ret;
 +}
diff --combined vss.c
index 269c0e0c4ac2d8ff1ed4c329db168fa26f869671,babcd24c9a1e55cf95b1dcb6d340e5b5d490cb06..85e7da85731a872b27bb91489a22f7796e7861be
--- 1/vss.c
--- 2/vss.c
+++ b/vss.c
@@@ -11,9 -11,7 +11,9 @@@
   * senders.
   */
  
 +#include <regex.h>
  #include <dirent.h>
 +#include <osl.h>
  
  #include "para.h"
  #include "error.h"
@@@ -234,6 -232,17 +234,17 @@@ static int num_slices(long unsigned byt
        return 1;
  }
  
+ static void set_slice_duration(struct fec_client *fc, struct fec_group *g)
+ {
+       struct timeval group_duration, *chunk_tv = vss_chunk_time();
+       tv_scale(g->num_chunks, chunk_tv, &group_duration);
+       tv_divide(fc->fcp->slices_per_group + fc->num_extra_slices,
+               &group_duration, &g->slice_duration);
+       PARA_DEBUG_LOG("durations (group/chunk/slice): %lu/%lu/%lu\n",
+               tv2ms(&group_duration), tv2ms(chunk_tv), tv2ms(&g->slice_duration));
+ }
  static int setup_next_fec_group(struct fec_client *fc, struct vss_task *vsst)
  {
        int ret, i, k, data_slices;
                g->first_chunk = mmd->current_chunk;
                g->num = 0;
        } else {
+               /* use duration of the previous group for the timing of this group */
+               set_slice_duration(fc, g);
                g->first_chunk += g->num_chunks;
                g->num++;
        }
        g->num_chunks = i - g->first_chunk;
        assert(g->num_chunks);
        fc->current_slice_num = 0;
+       if (g->num == 0)
+               set_slice_duration(fc, g);
  
        /* setup header slices */
        buf = vsst->header_buf;
                for (; i < k; i++)
                        fc->src_data[i] = (const unsigned char *)buf;
        }
-       /* setup group timing */
-       tv_scale(g->first_chunk - fc->first_stream_chunk, chunk_tv, &tmp);
-       tv_add(&fc->stream_start, &tmp, &g->start);
-       tv_scale(g->num_chunks, chunk_tv, &tmp); /* group duration */
-       tv_divide(fc->fcp->slices_per_group + fc->num_extra_slices,
-               &tmp, &g->slice_duration);
-       PARA_DEBUG_LOG("FEC group %d: %d chunks (%d - %d), %d header slices, %d data slices\n",
+       PARA_DEBUG_LOG("FEC group %d: %d chunks (%d - %d), "
+               "%d header slices, %d data slices\n",
                g->num, g->num_chunks, g->first_chunk,
                g->first_chunk + g->num_chunks - 1,
                g->num_header_slices, data_slices
        );
-       PARA_DEBUG_LOG("durations (group/chunk/slice): %lu/%lu/%lu\n",
-               tv2ms(&tmp), tv2ms(chunk_tv), tv2ms(&g->slice_duration));
+       /* set group start */
+       tv_scale(g->first_chunk - fc->first_stream_chunk, chunk_tv, &tmp);
+       tv_add(&fc->stream_start, &tmp, &g->start);
        return 1;
  }
  
@@@ -486,7 -493,8 +495,7 @@@ static void compute_slice_timeout(struc
  static void set_eof_barrier(struct vss_task *vsst)
  {
        struct fec_client *fc;
 -      struct timeval timeout = mmd->afd.afhi.eof_tv,
 -              *chunk_tv = vss_chunk_time();
 +      struct timeval timeout = {1, 0}, *chunk_tv = vss_chunk_time();
  
        if (!chunk_tv)
                goto out;
@@@ -628,6 -636,10 +637,6 @@@ static void vss_eof(struct vss_task *vs
        mmd->afd.afhi.chunk_tv.tv_usec = 0;
        free(mmd->afd.afhi.chunk_table);
        mmd->afd.afhi.chunk_table = NULL;
 -      free(mmd->afd.afhi.info_string);
 -      mmd->afd.afhi.info_string = make_message("%s:\n%s:\n%s:\n", status_item_list[SI_AUDIO_FILE_INFO],
 -              status_item_list[SI_TAGINFO1], status_item_list[SI_TAGINFO2]);
 -      make_empty_status_items(mmd->afd.verbose_ls_output);
        mmd->mtime = 0;
        mmd->size = 0;
        mmd->events++;
@@@ -776,6 -788,7 +785,6 @@@ static void recv_afs_result(struct vss_
        if (passed_fd < 0)
                goto err;
        shmid = afs_data;
 -      free(mmd->afd.afhi.info_string);
        ret = load_afd(shmid, &mmd->afd);
        if (ret < 0)
                goto err;
@@@ -821,7 -834,7 +830,7 @@@ err
   */
  static void vss_send(struct vss_task *vsst)
  {
-       int i, sent_something = 0;
+       int i, fec_active = 0;
        struct timeval due;
        struct fec_client *fc, *tmp_fc;
  
        list_for_each_entry_safe(fc, tmp_fc, &fec_client_list, node) {
                if (fc->error < 0)
                        continue;
-               if (!next_slice_is_due(fc, NULL))
+               if (!next_slice_is_due(fc, NULL)) {
+                       fec_active = 1;
                        continue;
+               }
                if (compute_next_fec_slice(fc, vsst) <= 0)
                        continue;
                PARA_DEBUG_LOG("sending %d:%d (%u bytes)\n", fc->group.num,
                        fc->fcp->max_slice_bytes,
                        fc->fcp->private_data);
                fc->current_slice_num++;
-               sent_something = 1;
+               fec_active = 1;
        }
        if (mmd->current_chunk >= mmd->afd.afhi.chunks_total) { /* eof */
-               if (!sent_something)
+               if (!fec_active)
                        mmd->new_vss_status_flags |= VSS_NEXT;
                return;
        }
@@@ -950,6 -965,7 +961,6 @@@ void init_vss_task(int afs_socket
        free(hn);
        free(home);
        mmd->sender_cmd_data.cmd_num = -1;
 -      make_empty_status_items(mmd->afd.verbose_ls_output);
        if (conf.autoplay_given) {
                struct timeval tmp;
                mmd->vss_status_flags |= VSS_PLAYING;