LCOV - code coverage report
Current view: top level - pulsecore - rtpoll.c (source / functions) Hit Total Coverage
Test: lcov.out Lines: 125 270 46.3 %
Date: 2012-07-17 Functions: 13 31 41.9 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 80 220 36.4 %

           Branch data     Line data    Source code
       1                 :            : /***
       2                 :            :   This file is part of PulseAudio.
       3                 :            : 
       4                 :            :   Copyright 2004-2006 Lennart Poettering
       5                 :            :   Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
       6                 :            : 
       7                 :            :   PulseAudio is free software; you can redistribute it and/or modify
       8                 :            :   it under the terms of the GNU Lesser General Public License as
       9                 :            :   published by the Free Software Foundation; either version 2.1 of the
      10                 :            :   License, or (at your option) any later version.
      11                 :            : 
      12                 :            :   PulseAudio is distributed in the hope that it will be useful, but
      13                 :            :   WITHOUT ANY WARRANTY; without even the implied warranty of
      14                 :            :   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
      15                 :            :   Lesser General Public License for more details.
      16                 :            : 
      17                 :            :   You should have received a copy of the GNU Lesser General Public
      18                 :            :   License along with PulseAudio; if not, write to the Free Software
      19                 :            :   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
      20                 :            :   USA.
      21                 :            : ***/
      22                 :            : 
      23                 :            : #ifdef HAVE_CONFIG_H
      24                 :            : #include <config.h>
      25                 :            : #endif
      26                 :            : 
      27                 :            : #include <sys/types.h>
      28                 :            : #include <stdio.h>
      29                 :            : #include <string.h>
      30                 :            : #include <errno.h>
      31                 :            : 
      32                 :            : #include <pulse/xmalloc.h>
      33                 :            : #include <pulse/timeval.h>
      34                 :            : 
      35                 :            : #include <pulsecore/poll.h>
      36                 :            : #include <pulsecore/core-error.h>
      37                 :            : #include <pulsecore/core-rtclock.h>
      38                 :            : #include <pulsecore/macro.h>
      39                 :            : #include <pulsecore/llist.h>
      40                 :            : #include <pulsecore/flist.h>
      41                 :            : #include <pulsecore/core-util.h>
      42                 :            : #include <pulsecore/ratelimit.h>
      43                 :            : #include <pulse/rtclock.h>
      44                 :            : 
      45                 :            : #include "rtpoll.h"
      46                 :            : 
      47                 :            : /* #define DEBUG_TIMING */
      48                 :            : 
      49                 :            : struct pa_rtpoll {
      50                 :            :     struct pollfd *pollfd, *pollfd2;
      51                 :            :     unsigned n_pollfd_alloc, n_pollfd_used;
      52                 :            : 
      53                 :            :     struct timeval next_elapse;
      54                 :            :     pa_bool_t timer_enabled:1;
      55                 :            : 
      56                 :            :     pa_bool_t scan_for_dead:1;
      57                 :            :     pa_bool_t running:1;
      58                 :            :     pa_bool_t rebuild_needed:1;
      59                 :            :     pa_bool_t quit:1;
      60                 :            :     pa_bool_t timer_elapsed:1;
      61                 :            : 
      62                 :            : #ifdef DEBUG_TIMING
      63                 :            :     pa_usec_t timestamp;
      64                 :            :     pa_usec_t slept, awake;
      65                 :            : #endif
      66                 :            : 
      67                 :            :     PA_LLIST_HEAD(pa_rtpoll_item, items);
      68                 :            : };
      69                 :            : 
      70                 :            : struct pa_rtpoll_item {
      71                 :            :     pa_rtpoll *rtpoll;
      72                 :            :     pa_bool_t dead;
      73                 :            : 
      74                 :            :     pa_rtpoll_priority_t priority;
      75                 :            : 
      76                 :            :     struct pollfd *pollfd;
      77                 :            :     unsigned n_pollfd;
      78                 :            : 
      79                 :            :     int (*work_cb)(pa_rtpoll_item *i);
      80                 :            :     int (*before_cb)(pa_rtpoll_item *i);
      81                 :            :     void (*after_cb)(pa_rtpoll_item *i);
      82                 :            :     void *userdata;
      83                 :            : 
      84                 :            :     PA_LLIST_FIELDS(pa_rtpoll_item);
      85                 :            : };
      86                 :            : 
      87 [ -  + ][ #  # ]:         28 : PA_STATIC_FLIST_DECLARE(items, 0, pa_xfree);
      88                 :            : 
      89                 :          1 : pa_rtpoll *pa_rtpoll_new(void) {
      90                 :            :     pa_rtpoll *p;
      91                 :            : 
      92                 :          1 :     p = pa_xnew0(pa_rtpoll, 1);
      93                 :            : 
      94                 :          1 :     p->n_pollfd_alloc = 32;
      95                 :          1 :     p->pollfd = pa_xnew(struct pollfd, p->n_pollfd_alloc);
      96                 :          1 :     p->pollfd2 = pa_xnew(struct pollfd, p->n_pollfd_alloc);
      97                 :            : 
      98                 :            : #ifdef DEBUG_TIMING
      99                 :            :     p->timestamp = pa_rtclock_now();
     100                 :            : #endif
     101                 :            : 
     102                 :          1 :     return p;
     103                 :            : }
     104                 :            : 
     105                 :          2 : static void rtpoll_rebuild(pa_rtpoll *p) {
     106                 :            : 
     107                 :            :     struct pollfd *e, *t;
     108                 :            :     pa_rtpoll_item *i;
     109                 :          2 :     int ra = 0;
     110                 :            : 
     111         [ -  + ]:          2 :     pa_assert(p);
     112                 :            : 
     113                 :          2 :     p->rebuild_needed = FALSE;
     114                 :            : 
     115         [ -  + ]:          2 :     if (p->n_pollfd_used > p->n_pollfd_alloc) {
     116                 :            :         /* Hmm, we have to allocate some more space */
     117                 :          0 :         p->n_pollfd_alloc = p->n_pollfd_used * 2;
     118                 :          0 :         p->pollfd2 = pa_xrealloc(p->pollfd2, p->n_pollfd_alloc * sizeof(struct pollfd));
     119                 :          0 :         ra = 1;
     120                 :            :     }
     121                 :            : 
     122                 :          2 :     e = p->pollfd2;
     123                 :            : 
     124         [ +  + ]:          5 :     for (i = p->items; i; i = i->next) {
     125                 :            : 
     126         [ +  + ]:          3 :         if (i->n_pollfd > 0) {
     127                 :          2 :             size_t l = i->n_pollfd * sizeof(struct pollfd);
     128                 :            : 
     129         [ -  + ]:          2 :             if (i->pollfd)
     130                 :          0 :                 memcpy(e, i->pollfd, l);
     131                 :            :             else
     132                 :            :                 memset(e, 0, l);
     133                 :            : 
     134                 :          2 :             i->pollfd = e;
     135                 :            :         } else
     136                 :          1 :             i->pollfd = NULL;
     137                 :            : 
     138                 :          3 :         e += i->n_pollfd;
     139                 :            :     }
     140                 :            : 
     141         [ -  + ]:          2 :     pa_assert((unsigned) (e - p->pollfd2) == p->n_pollfd_used);
     142                 :          2 :     t = p->pollfd;
     143                 :          2 :     p->pollfd = p->pollfd2;
     144                 :          2 :     p->pollfd2 = t;
     145                 :            : 
     146         [ -  + ]:          2 :     if (ra)
     147                 :          0 :         p->pollfd2 = pa_xrealloc(p->pollfd2, p->n_pollfd_alloc * sizeof(struct pollfd));
     148                 :          2 : }
     149                 :            : 
     150                 :          3 : static void rtpoll_item_destroy(pa_rtpoll_item *i) {
     151                 :            :     pa_rtpoll *p;
     152                 :            : 
     153         [ -  + ]:          3 :     pa_assert(i);
     154                 :            : 
     155                 :          3 :     p = i->rtpoll;
     156                 :            : 
     157 [ -  + ][ +  + ]:          3 :     PA_LLIST_REMOVE(pa_rtpoll_item, p->items, i);
         [ -  + ][ -  + ]
     158                 :            : 
     159                 :          3 :     p->n_pollfd_used -= i->n_pollfd;
     160                 :            : 
     161         [ -  + ]:          3 :     if (pa_flist_push(PA_STATIC_FLIST_GET(items), i) < 0)
     162                 :          0 :         pa_xfree(i);
     163                 :            : 
     164                 :          3 :     p->rebuild_needed = TRUE;
     165                 :          3 : }
     166                 :            : 
     167                 :          1 : void pa_rtpoll_free(pa_rtpoll *p) {
     168         [ +  - ]:          1 :     pa_assert(p);
     169                 :            : 
     170         [ -  + ]:          1 :     while (p->items)
     171                 :          0 :         rtpoll_item_destroy(p->items);
     172                 :            : 
     173                 :          1 :     pa_xfree(p->pollfd);
     174                 :          1 :     pa_xfree(p->pollfd2);
     175                 :            : 
     176                 :          1 :     pa_xfree(p);
     177                 :          1 : }
     178                 :            : 
     179                 :            : static void reset_revents(pa_rtpoll_item *i) {
     180                 :            :     struct pollfd *f;
     181                 :            :     unsigned n;
     182                 :            : 
     183         [ #  # ]:          0 :     pa_assert(i);
     184                 :            : 
     185         [ #  # ]:          0 :     if (!(f = pa_rtpoll_item_get_pollfd(i, &n)))
     186                 :            :         return;
     187                 :            : 
     188         [ #  # ]:          0 :     for (; n > 0; n--)
     189                 :          0 :         f[n-1].revents = 0;
     190                 :            : }
     191                 :            : 
     192                 :          0 : static void reset_all_revents(pa_rtpoll *p) {
     193                 :            :     pa_rtpoll_item *i;
     194                 :            : 
     195         [ #  # ]:          0 :     pa_assert(p);
     196                 :            : 
     197         [ #  # ]:          0 :     for (i = p->items; i; i = i->next) {
     198                 :            : 
     199         [ #  # ]:          0 :         if (i->dead)
     200                 :          0 :             continue;
     201                 :            : 
     202                 :            :         reset_revents(i);
     203                 :            :     }
     204                 :          0 : }
     205                 :            : 
     206                 :          2 : int pa_rtpoll_run(pa_rtpoll *p, pa_bool_t wait_op) {
     207                 :            :     pa_rtpoll_item *i;
     208                 :          2 :     int r = 0;
     209                 :            :     struct timeval timeout;
     210                 :            : 
     211         [ -  + ]:          2 :     pa_assert(p);
     212         [ -  + ]:          2 :     pa_assert(!p->running);
     213                 :            : 
     214                 :            : #ifdef DEBUG_TIMING
     215                 :            :     pa_log("rtpoll_run");
     216                 :            : #endif
     217                 :            : 
     218                 :          2 :     p->running = TRUE;
     219                 :          2 :     p->timer_elapsed = FALSE;
     220                 :            : 
     221                 :            :     /* First, let's do some work */
     222 [ +  + ][ +  - ]:          6 :     for (i = p->items; i && i->priority < PA_RTPOLL_NEVER; i = i->next) {
     223                 :            :         int k;
     224                 :            : 
     225         [ -  + ]:          4 :         if (i->dead)
     226                 :          0 :             continue;
     227                 :            : 
     228         [ +  - ]:          4 :         if (!i->work_cb)
     229                 :          4 :             continue;
     230                 :            : 
     231         [ #  # ]:          0 :         if (p->quit) {
     232                 :            : #ifdef DEBUG_TIMING
     233                 :            :             pa_log("rtpoll finish");
     234                 :            : #endif
     235                 :            :             goto finish;
     236                 :            :         }
     237                 :            : 
     238         [ #  # ]:          0 :         if ((k = i->work_cb(i)) != 0) {
     239         [ #  # ]:          0 :             if (k < 0)
     240                 :          0 :                 r = k;
     241                 :            : #ifdef DEBUG_TIMING
     242                 :            :             pa_log("rtpoll finish");
     243                 :            : #endif
     244                 :            :             goto finish;
     245                 :            :         }
     246                 :            :     }
     247                 :            : 
     248                 :            :     /* Now let's prepare for entering the sleep */
     249 [ +  + ][ +  - ]:          6 :     for (i = p->items; i && i->priority < PA_RTPOLL_NEVER; i = i->next) {
     250                 :          4 :         int k = 0;
     251                 :            : 
     252         [ -  + ]:          4 :         if (i->dead)
     253                 :          0 :             continue;
     254                 :            : 
     255         [ -  + ]:          4 :         if (!i->before_cb)
     256                 :          0 :             continue;
     257                 :            : 
     258 [ +  - ][ -  + ]:          4 :         if (p->quit || (k = i->before_cb(i)) != 0) {
     259                 :            : 
     260                 :            :             /* Hmm, this one doesn't let us enter the poll, so rewind everything */
     261                 :            : 
     262         [ #  # ]:          0 :             for (i = i->prev; i; i = i->prev) {
     263                 :            : 
     264         [ #  # ]:          0 :                 if (i->dead)
     265                 :          0 :                     continue;
     266                 :            : 
     267         [ #  # ]:          0 :                 if (!i->after_cb)
     268                 :          0 :                     continue;
     269                 :            : 
     270                 :          0 :                 i->after_cb(i);
     271                 :            :             }
     272                 :            : 
     273         [ #  # ]:          0 :             if (k < 0)
     274                 :          0 :                 r = k;
     275                 :            : #ifdef DEBUG_TIMING
     276                 :            :             pa_log("rtpoll finish");
     277                 :            : #endif
     278                 :            :             goto finish;
     279                 :            :         }
     280                 :            :     }
     281                 :            : 
     282         [ -  + ]:          2 :     if (p->rebuild_needed)
     283                 :          0 :         rtpoll_rebuild(p);
     284                 :            : 
     285                 :            :     pa_zero(timeout);
     286                 :            : 
     287                 :            :     /* Calculate timeout */
     288 [ +  - ][ +  - ]:          2 :     if (wait_op && !p->quit && p->timer_enabled) {
                 [ +  - ]
     289                 :            :         struct timeval now;
     290                 :          2 :         pa_rtclock_get(&now);
     291                 :            : 
     292         [ +  + ]:          2 :         if (pa_timeval_cmp(&p->next_elapse, &now) > 0)
     293                 :          1 :             pa_timeval_add(&timeout, pa_timeval_diff(&p->next_elapse, &now));
     294                 :            :     }
     295                 :            : 
     296                 :            : #ifdef DEBUG_TIMING
     297                 :            :     {
     298                 :            :         pa_usec_t now = pa_rtclock_now();
     299                 :            :         p->awake = now - p->timestamp;
     300                 :            :         p->timestamp = now;
     301                 :            :         if (!wait_op || p->quit || p->timer_enabled)
     302                 :            :             pa_log("poll timeout: %d ms ",(int) ((timeout.tv_sec*1000) + (timeout.tv_usec / 1000)));
     303                 :            :         else
     304                 :            :             pa_log("poll timeout is ZERO");
     305                 :            :     }
     306                 :            : #endif
     307                 :            : 
     308                 :            :     /* OK, now let's sleep */
     309                 :            : #ifdef HAVE_PPOLL
     310                 :            :     {
     311                 :            :         struct timespec ts;
     312                 :          2 :         ts.tv_sec = timeout.tv_sec;
     313                 :          2 :         ts.tv_nsec = timeout.tv_usec * 1000;
     314 [ +  - ][ +  - ]:          2 :         r = ppoll(p->pollfd, p->n_pollfd_used, (!wait_op || p->quit || p->timer_enabled) ? &ts : NULL, NULL);
                 [ -  + ]
     315                 :            :     }
     316                 :            : #else
     317                 :            :     r = pa_poll(p->pollfd, p->n_pollfd_used, (!wait_op || p->quit || p->timer_enabled) ? (int) ((timeout.tv_sec*1000) + (timeout.tv_usec / 1000)) : -1);
     318                 :            : #endif
     319                 :            : 
     320                 :          2 :     p->timer_elapsed = r == 0;
     321                 :            : 
     322                 :            : #ifdef DEBUG_TIMING
     323                 :            :     {
     324                 :            :         pa_usec_t now = pa_rtclock_now();
     325                 :            :         p->slept = now - p->timestamp;
     326                 :            :         p->timestamp = now;
     327                 :            : 
     328                 :            :         pa_log("Process time %llu ms; sleep time %llu ms",
     329                 :            :                (unsigned long long) (p->awake / PA_USEC_PER_MSEC),
     330                 :            :                (unsigned long long) (p->slept / PA_USEC_PER_MSEC));
     331                 :            :     }
     332                 :            : #endif
     333                 :            : 
     334         [ -  + ]:          2 :     if (r < 0) {
     335         [ #  # ]:          0 :         if (errno == EAGAIN || errno == EINTR)
     336                 :            :             r = 0;
     337                 :            :         else
     338                 :          0 :             pa_log_error("poll(): %s", pa_cstrerror(errno));
     339                 :            : 
     340                 :          0 :         reset_all_revents(p);
     341                 :            :     }
     342                 :            : 
     343                 :            :     /* Let's tell everyone that we left the sleep */
     344 [ +  + ][ +  - ]:          6 :     for (i = p->items; i && i->priority < PA_RTPOLL_NEVER; i = i->next) {
     345                 :            : 
     346         [ -  + ]:          4 :         if (i->dead)
     347                 :          0 :             continue;
     348                 :            : 
     349         [ +  + ]:          4 :         if (!i->after_cb)
     350                 :          2 :             continue;
     351                 :            : 
     352                 :          2 :         i->after_cb(i);
     353                 :            :     }
     354                 :            : 
     355                 :            : finish:
     356                 :            : 
     357                 :          2 :     p->running = FALSE;
     358                 :            : 
     359         [ -  + ]:          2 :     if (p->scan_for_dead) {
     360                 :            :         pa_rtpoll_item *n;
     361                 :            : 
     362                 :          0 :         p->scan_for_dead = FALSE;
     363                 :            : 
     364         [ #  # ]:          0 :         for (i = p->items; i; i = n) {
     365                 :          0 :             n = i->next;
     366                 :            : 
     367         [ #  # ]:          0 :             if (i->dead)
     368                 :          0 :                 rtpoll_item_destroy(i);
     369                 :            :         }
     370                 :            :     }
     371                 :            : 
     372         [ +  - ]:          2 :     return r < 0 ? r : !p->quit;
     373                 :            : }
     374                 :            : 
     375                 :          0 : void pa_rtpoll_set_timer_absolute(pa_rtpoll *p, pa_usec_t usec) {
     376         [ #  # ]:          0 :     pa_assert(p);
     377                 :            : 
     378                 :          0 :     pa_timeval_store(&p->next_elapse, usec);
     379                 :          0 :     p->timer_enabled = TRUE;
     380                 :          0 : }
     381                 :            : 
     382                 :          1 : void pa_rtpoll_set_timer_relative(pa_rtpoll *p, pa_usec_t usec) {
     383         [ -  + ]:          1 :     pa_assert(p);
     384                 :            : 
     385                 :            :     /* Scheduling a timeout for more than an hour is very very suspicious */
     386         [ -  + ]:          1 :     pa_assert(usec <= PA_USEC_PER_SEC*60ULL*60ULL);
     387                 :            : 
     388                 :          1 :     pa_rtclock_get(&p->next_elapse);
     389                 :          1 :     pa_timeval_add(&p->next_elapse, usec);
     390                 :          1 :     p->timer_enabled = TRUE;
     391                 :          1 : }
     392                 :            : 
     393                 :          0 : void pa_rtpoll_set_timer_disabled(pa_rtpoll *p) {
     394         [ #  # ]:          0 :     pa_assert(p);
     395                 :            : 
     396                 :          0 :     memset(&p->next_elapse, 0, sizeof(p->next_elapse));
     397                 :          0 :     p->timer_enabled = FALSE;
     398                 :          0 : }
     399                 :            : 
     400                 :          3 : pa_rtpoll_item *pa_rtpoll_item_new(pa_rtpoll *p, pa_rtpoll_priority_t prio, unsigned n_fds) {
     401                 :          3 :     pa_rtpoll_item *i, *j, *l = NULL;
     402                 :            : 
     403         [ -  + ]:          3 :     pa_assert(p);
     404                 :            : 
     405         [ +  + ]:          3 :     if (!(i = pa_flist_pop(PA_STATIC_FLIST_GET(items))))
     406                 :          2 :         i = pa_xnew(pa_rtpoll_item, 1);
     407                 :            : 
     408                 :          3 :     i->rtpoll = p;
     409                 :          3 :     i->dead = FALSE;
     410                 :          3 :     i->n_pollfd = n_fds;
     411                 :          3 :     i->pollfd = NULL;
     412                 :          3 :     i->priority = prio;
     413                 :            : 
     414                 :          3 :     i->userdata = NULL;
     415                 :          3 :     i->before_cb = NULL;
     416                 :          3 :     i->after_cb = NULL;
     417                 :          3 :     i->work_cb = NULL;
     418                 :            : 
     419         [ +  + ]:          4 :     for (j = p->items; j; j = j->next) {
     420         [ +  + ]:          2 :         if (prio <= j->priority)
     421                 :            :             break;
     422                 :            : 
     423                 :          1 :         l = j;
     424                 :            :     }
     425                 :            : 
     426 [ +  + ][ -  + ]:          3 :     PA_LLIST_INSERT_AFTER(pa_rtpoll_item, p->items, j ? j->prev : l, i);
         [ +  + ][ +  + ]
                 [ -  + ]
     427                 :            : 
     428         [ +  + ]:          3 :     if (n_fds > 0) {
     429                 :          2 :         p->rebuild_needed = 1;
     430                 :          2 :         p->n_pollfd_used += n_fds;
     431                 :            :     }
     432                 :            : 
     433                 :          3 :     return i;
     434                 :            : }
     435                 :            : 
     436                 :          3 : void pa_rtpoll_item_free(pa_rtpoll_item *i) {
     437         [ -  + ]:          3 :     pa_assert(i);
     438                 :            : 
     439         [ -  + ]:          3 :     if (i->rtpoll->running) {
     440                 :          0 :         i->dead = TRUE;
     441                 :          0 :         i->rtpoll->scan_for_dead = TRUE;
     442                 :          3 :         return;
     443                 :            :     }
     444                 :            : 
     445                 :          3 :     rtpoll_item_destroy(i);
     446                 :            : }
     447                 :            : 
     448                 :          2 : struct pollfd *pa_rtpoll_item_get_pollfd(pa_rtpoll_item *i, unsigned *n_fds) {
     449         [ -  + ]:          2 :     pa_assert(i);
     450                 :            : 
     451         [ +  - ]:          2 :     if (i->n_pollfd > 0)
     452         [ +  - ]:          2 :         if (i->rtpoll->rebuild_needed)
     453                 :          2 :             rtpoll_rebuild(i->rtpoll);
     454                 :            : 
     455         [ -  + ]:          2 :     if (n_fds)
     456                 :          0 :         *n_fds = i->n_pollfd;
     457                 :            : 
     458                 :          2 :     return i->pollfd;
     459                 :            : }
     460                 :            : 
     461                 :          3 : void pa_rtpoll_item_set_before_callback(pa_rtpoll_item *i, int (*before_cb)(pa_rtpoll_item *i)) {
     462         [ -  + ]:          3 :     pa_assert(i);
     463         [ -  + ]:          3 :     pa_assert(i->priority < PA_RTPOLL_NEVER);
     464                 :            : 
     465                 :          3 :     i->before_cb = before_cb;
     466                 :          3 : }
     467                 :            : 
     468                 :          2 : void pa_rtpoll_item_set_after_callback(pa_rtpoll_item *i, void (*after_cb)(pa_rtpoll_item *i)) {
     469         [ -  + ]:          2 :     pa_assert(i);
     470         [ -  + ]:          2 :     pa_assert(i->priority < PA_RTPOLL_NEVER);
     471                 :            : 
     472                 :          2 :     i->after_cb = after_cb;
     473                 :          2 : }
     474                 :            : 
     475                 :          0 : void pa_rtpoll_item_set_work_callback(pa_rtpoll_item *i, int (*work_cb)(pa_rtpoll_item *i)) {
     476         [ #  # ]:          0 :     pa_assert(i);
     477         [ #  # ]:          0 :     pa_assert(i->priority < PA_RTPOLL_NEVER);
     478                 :            : 
     479                 :          0 :     i->work_cb = work_cb;
     480                 :          0 : }
     481                 :            : 
     482                 :          0 : void pa_rtpoll_item_set_userdata(pa_rtpoll_item *i, void *userdata) {
     483         [ #  # ]:          0 :     pa_assert(i);
     484                 :            : 
     485                 :          0 :     i->userdata = userdata;
     486                 :          0 : }
     487                 :            : 
     488                 :          0 : void* pa_rtpoll_item_get_userdata(pa_rtpoll_item *i) {
     489         [ #  # ]:          0 :     pa_assert(i);
     490                 :            : 
     491                 :          0 :     return i->userdata;
     492                 :            : }
     493                 :            : 
     494                 :          0 : static int fdsem_before(pa_rtpoll_item *i) {
     495                 :            : 
     496         [ #  # ]:          0 :     if (pa_fdsem_before_poll(i->userdata) < 0)
     497                 :            :         return 1; /* 1 means immediate restart of the loop */
     498                 :            : 
     499                 :          0 :     return 0;
     500                 :            : }
     501                 :            : 
     502                 :          0 : static void fdsem_after(pa_rtpoll_item *i) {
     503         [ #  # ]:          0 :     pa_assert(i);
     504                 :            : 
     505         [ #  # ]:          0 :     pa_assert((i->pollfd[0].revents & ~POLLIN) == 0);
     506                 :          0 :     pa_fdsem_after_poll(i->userdata);
     507                 :          0 : }
     508                 :            : 
     509                 :          0 : pa_rtpoll_item *pa_rtpoll_item_new_fdsem(pa_rtpoll *p, pa_rtpoll_priority_t prio, pa_fdsem *f) {
     510                 :            :     pa_rtpoll_item *i;
     511                 :            :     struct pollfd *pollfd;
     512                 :            : 
     513         [ #  # ]:          0 :     pa_assert(p);
     514         [ #  # ]:          0 :     pa_assert(f);
     515                 :            : 
     516                 :          0 :     i = pa_rtpoll_item_new(p, prio, 1);
     517                 :            : 
     518                 :          0 :     pollfd = pa_rtpoll_item_get_pollfd(i, NULL);
     519                 :            : 
     520                 :          0 :     pollfd->fd = pa_fdsem_get(f);
     521                 :          0 :     pollfd->events = POLLIN;
     522                 :            : 
     523                 :          0 :     i->before_cb = fdsem_before;
     524                 :          0 :     i->after_cb = fdsem_after;
     525                 :          0 :     i->userdata = f;
     526                 :            : 
     527                 :          0 :     return i;
     528                 :            : }
     529                 :            : 
     530                 :          0 : static int asyncmsgq_read_before(pa_rtpoll_item *i) {
     531         [ #  # ]:          0 :     pa_assert(i);
     532                 :            : 
     533         [ #  # ]:          0 :     if (pa_asyncmsgq_read_before_poll(i->userdata) < 0)
     534                 :            :         return 1; /* 1 means immediate restart of the loop */
     535                 :            : 
     536                 :          0 :     return 0;
     537                 :            : }
     538                 :            : 
     539                 :          0 : static void asyncmsgq_read_after(pa_rtpoll_item *i) {
     540         [ #  # ]:          0 :     pa_assert(i);
     541                 :            : 
     542         [ #  # ]:          0 :     pa_assert((i->pollfd[0].revents & ~POLLIN) == 0);
     543                 :          0 :     pa_asyncmsgq_read_after_poll(i->userdata);
     544                 :          0 : }
     545                 :            : 
     546                 :          0 : static int asyncmsgq_read_work(pa_rtpoll_item *i) {
     547                 :            :     pa_msgobject *object;
     548                 :            :     int code;
     549                 :            :     void *data;
     550                 :            :     pa_memchunk chunk;
     551                 :            :     int64_t offset;
     552                 :            : 
     553         [ #  # ]:          0 :     pa_assert(i);
     554                 :            : 
     555         [ #  # ]:          0 :     if (pa_asyncmsgq_get(i->userdata, &object, &code, &data, &offset, &chunk, 0) == 0) {
     556                 :            :         int ret;
     557                 :            : 
     558 [ #  # ][ #  # ]:          0 :         if (!object && code == PA_MESSAGE_SHUTDOWN) {
     559                 :          0 :             pa_asyncmsgq_done(i->userdata, 0);
     560                 :          0 :             pa_rtpoll_quit(i->rtpoll);
     561                 :          0 :             return 1;
     562                 :            :         }
     563                 :            : 
     564                 :          0 :         ret = pa_asyncmsgq_dispatch(object, code, data, offset, &chunk);
     565                 :          0 :         pa_asyncmsgq_done(i->userdata, ret);
     566                 :          0 :         return 1;
     567                 :            :     }
     568                 :            : 
     569                 :            :     return 0;
     570                 :            : }
     571                 :            : 
     572                 :          0 : pa_rtpoll_item *pa_rtpoll_item_new_asyncmsgq_read(pa_rtpoll *p, pa_rtpoll_priority_t prio, pa_asyncmsgq *q) {
     573                 :            :     pa_rtpoll_item *i;
     574                 :            :     struct pollfd *pollfd;
     575                 :            : 
     576         [ #  # ]:          0 :     pa_assert(p);
     577         [ #  # ]:          0 :     pa_assert(q);
     578                 :            : 
     579                 :          0 :     i = pa_rtpoll_item_new(p, prio, 1);
     580                 :            : 
     581                 :          0 :     pollfd = pa_rtpoll_item_get_pollfd(i, NULL);
     582                 :          0 :     pollfd->fd = pa_asyncmsgq_read_fd(q);
     583                 :          0 :     pollfd->events = POLLIN;
     584                 :            : 
     585                 :          0 :     i->before_cb = asyncmsgq_read_before;
     586                 :          0 :     i->after_cb = asyncmsgq_read_after;
     587                 :          0 :     i->work_cb = asyncmsgq_read_work;
     588                 :          0 :     i->userdata = q;
     589                 :            : 
     590                 :          0 :     return i;
     591                 :            : }
     592                 :            : 
     593                 :          0 : static int asyncmsgq_write_before(pa_rtpoll_item *i) {
     594         [ #  # ]:          0 :     pa_assert(i);
     595                 :            : 
     596                 :          0 :     pa_asyncmsgq_write_before_poll(i->userdata);
     597                 :          0 :     return 0;
     598                 :            : }
     599                 :            : 
     600                 :          0 : static void asyncmsgq_write_after(pa_rtpoll_item *i) {
     601         [ #  # ]:          0 :     pa_assert(i);
     602                 :            : 
     603         [ #  # ]:          0 :     pa_assert((i->pollfd[0].revents & ~POLLIN) == 0);
     604                 :          0 :     pa_asyncmsgq_write_after_poll(i->userdata);
     605                 :          0 : }
     606                 :            : 
     607                 :          0 : pa_rtpoll_item *pa_rtpoll_item_new_asyncmsgq_write(pa_rtpoll *p, pa_rtpoll_priority_t prio, pa_asyncmsgq *q) {
     608                 :            :     pa_rtpoll_item *i;
     609                 :            :     struct pollfd *pollfd;
     610                 :            : 
     611         [ #  # ]:          0 :     pa_assert(p);
     612         [ #  # ]:          0 :     pa_assert(q);
     613                 :            : 
     614                 :          0 :     i = pa_rtpoll_item_new(p, prio, 1);
     615                 :            : 
     616                 :          0 :     pollfd = pa_rtpoll_item_get_pollfd(i, NULL);
     617                 :          0 :     pollfd->fd = pa_asyncmsgq_write_fd(q);
     618                 :          0 :     pollfd->events = POLLIN;
     619                 :            : 
     620                 :          0 :     i->before_cb = asyncmsgq_write_before;
     621                 :          0 :     i->after_cb = asyncmsgq_write_after;
     622                 :          0 :     i->work_cb = NULL;
     623                 :          0 :     i->userdata = q;
     624                 :            : 
     625                 :          0 :     return i;
     626                 :            : }
     627                 :            : 
     628                 :          0 : void pa_rtpoll_quit(pa_rtpoll *p) {
     629         [ #  # ]:          0 :     pa_assert(p);
     630                 :            : 
     631                 :          0 :     p->quit = TRUE;
     632                 :          0 : }
     633                 :            : 
     634                 :          0 : pa_bool_t pa_rtpoll_timer_elapsed(pa_rtpoll *p) {
     635         [ #  # ]:          0 :     pa_assert(p);
     636                 :            : 
     637                 :          0 :     return p->timer_elapsed;
     638                 :            : }

Generated by: LCOV version 1.9