LCOV - code coverage report
Current view: top level - pulsecore - pdispatch.c (source / functions) Hit Total Coverage
Test: lcov.out Lines: 1 124 0.8 %
Date: 2012-07-17 Functions: 1 14 7.1 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 1 130 0.8 %

           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 <stdio.h>
      28                 :            : #include <stdlib.h>
      29                 :            : 
      30                 :            : #include <pulse/rtclock.h>
      31                 :            : #include <pulse/timeval.h>
      32                 :            : #include <pulse/xmalloc.h>
      33                 :            : 
      34                 :            : #include <pulsecore/native-common.h>
      35                 :            : #include <pulsecore/llist.h>
      36                 :            : #include <pulsecore/log.h>
      37                 :            : #include <pulsecore/core-util.h>
      38                 :            : #include <pulsecore/macro.h>
      39                 :            : #include <pulsecore/refcnt.h>
      40                 :            : #include <pulsecore/flist.h>
      41                 :            : #include <pulsecore/core-rtclock.h>
      42                 :            : 
      43                 :            : #include "pdispatch.h"
      44                 :            : 
      45                 :            : /* #define DEBUG_OPCODES */
      46                 :            : 
      47                 :            : #ifdef DEBUG_OPCODES
      48                 :            : 
      49                 :            : static const char *command_names[PA_COMMAND_MAX] = {
      50                 :            :     /* Generic commands */
      51                 :            :     [PA_COMMAND_ERROR] = "ERROR",
      52                 :            :     [PA_COMMAND_TIMEOUT] = "TIMEOUT",
      53                 :            :     [PA_COMMAND_REPLY] = "REPLY",
      54                 :            : 
      55                 :            :     /* CLIENT->SERVER */
      56                 :            :     [PA_COMMAND_CREATE_PLAYBACK_STREAM] = "CREATE_PLAYBACK_STREAM",
      57                 :            :     [PA_COMMAND_DELETE_PLAYBACK_STREAM] = "DELETE_PLAYBACK_STREAM",
      58                 :            :     [PA_COMMAND_CREATE_RECORD_STREAM] = "CREATE_RECORD_STREAM",
      59                 :            :     [PA_COMMAND_DELETE_RECORD_STREAM] = "DELETE_RECORD_STREAM",
      60                 :            :     [PA_COMMAND_AUTH] = "AUTH",
      61                 :            :     [PA_COMMAND_EXIT] = "EXIT",
      62                 :            :     [PA_COMMAND_SET_CLIENT_NAME] = "SET_CLIENT_NAME",
      63                 :            :     [PA_COMMAND_LOOKUP_SINK] = "LOOKUP_SINK",
      64                 :            :     [PA_COMMAND_LOOKUP_SOURCE] = "LOOKUP_SOURCE",
      65                 :            :     [PA_COMMAND_DRAIN_PLAYBACK_STREAM] = "DRAIN_PLAYBACK_STREAM",
      66                 :            :     [PA_COMMAND_STAT] = "STAT",
      67                 :            :     [PA_COMMAND_GET_PLAYBACK_LATENCY] = "GET_PLAYBACK_LATENCY",
      68                 :            :     [PA_COMMAND_CREATE_UPLOAD_STREAM] = "CREATE_UPLOAD_STREAM",
      69                 :            :     [PA_COMMAND_DELETE_UPLOAD_STREAM] = "DELETE_UPLOAD_STREAM",
      70                 :            :     [PA_COMMAND_FINISH_UPLOAD_STREAM] = "FINISH_UPLOAD_STREAM",
      71                 :            :     [PA_COMMAND_PLAY_SAMPLE] = "PLAY_SAMPLE",
      72                 :            :     [PA_COMMAND_REMOVE_SAMPLE] = "REMOVE_SAMPLE",
      73                 :            : 
      74                 :            :     [PA_COMMAND_GET_SERVER_INFO] = "GET_SERVER_INFO",
      75                 :            :     [PA_COMMAND_GET_SINK_INFO] = "GET_SINK_INFO",
      76                 :            :     [PA_COMMAND_GET_SINK_INFO_LIST] = "GET_SINK_INFO_LIST",
      77                 :            :     [PA_COMMAND_GET_SOURCE_INFO] = "GET_SOURCE_INFO",
      78                 :            :     [PA_COMMAND_GET_SOURCE_INFO_LIST] = "GET_SOURCE_INFO_LIST",
      79                 :            :     [PA_COMMAND_GET_MODULE_INFO] = "GET_MODULE_INFO",
      80                 :            :     [PA_COMMAND_GET_MODULE_INFO_LIST] = "GET_MODULE_INFO_LIST",
      81                 :            :     [PA_COMMAND_GET_CLIENT_INFO] = "GET_CLIENT_INFO",
      82                 :            :     [PA_COMMAND_GET_CLIENT_INFO_LIST] = "GET_CLIENT_INFO_LIST",
      83                 :            :     [PA_COMMAND_GET_SAMPLE_INFO] = "GET_SAMPLE_INFO",
      84                 :            :     [PA_COMMAND_GET_SAMPLE_INFO_LIST] = "GET_SAMPLE_INFO_LIST",
      85                 :            :     [PA_COMMAND_GET_SINK_INPUT_INFO] = "GET_SINK_INPUT_INFO",
      86                 :            :     [PA_COMMAND_GET_SINK_INPUT_INFO_LIST] = "GET_SINK_INPUT_INFO_LIST",
      87                 :            :     [PA_COMMAND_GET_SOURCE_OUTPUT_INFO] = "GET_SOURCE_OUTPUT_INFO",
      88                 :            :     [PA_COMMAND_GET_SOURCE_OUTPUT_INFO_LIST] = "GET_SOURCE_OUTPUT_INFO_LIST",
      89                 :            :     [PA_COMMAND_SUBSCRIBE] = "SUBSCRIBE",
      90                 :            : 
      91                 :            :     [PA_COMMAND_SET_SINK_VOLUME] = "SET_SINK_VOLUME",
      92                 :            :     [PA_COMMAND_SET_SINK_INPUT_VOLUME] = "SET_SINK_INPUT_VOLUME",
      93                 :            :     [PA_COMMAND_SET_SOURCE_VOLUME] = "SET_SOURCE_VOLUME",
      94                 :            : 
      95                 :            :     [PA_COMMAND_SET_SINK_MUTE] = "SET_SINK_MUTE",
      96                 :            :     [PA_COMMAND_SET_SOURCE_MUTE] = "SET_SOURCE_MUTE",
      97                 :            : 
      98                 :            :     [PA_COMMAND_TRIGGER_PLAYBACK_STREAM] = "TRIGGER_PLAYBACK_STREAM",
      99                 :            :     [PA_COMMAND_FLUSH_PLAYBACK_STREAM] = "FLUSH_PLAYBACK_STREAM",
     100                 :            :     [PA_COMMAND_CORK_PLAYBACK_STREAM] = "CORK_PLAYBACK_STREAM",
     101                 :            : 
     102                 :            :     [PA_COMMAND_SET_DEFAULT_SINK] = "SET_DEFAULT_SINK",
     103                 :            :     [PA_COMMAND_SET_DEFAULT_SOURCE] = "SET_DEFAULT_SOURCE",
     104                 :            : 
     105                 :            :     [PA_COMMAND_SET_PLAYBACK_STREAM_NAME] = "SET_PLAYBACK_STREAM_NAME",
     106                 :            :     [PA_COMMAND_SET_RECORD_STREAM_NAME] = "SET_RECORD_STREAM_NAME",
     107                 :            : 
     108                 :            :     [PA_COMMAND_KILL_CLIENT] = "KILL_CLIENT",
     109                 :            :     [PA_COMMAND_KILL_SINK_INPUT] = "KILL_SINK_INPUT",
     110                 :            :     [PA_COMMAND_KILL_SOURCE_OUTPUT] = "SOURCE_OUTPUT",
     111                 :            : 
     112                 :            :     [PA_COMMAND_LOAD_MODULE] = "LOAD_MODULE",
     113                 :            :     [PA_COMMAND_UNLOAD_MODULE] = "UNLOAD_MODULE",
     114                 :            : 
     115                 :            :     [PA_COMMAND_ADD_AUTOLOAD___OBSOLETE] = "ADD_AUTOLOAD (obsolete)",
     116                 :            :     [PA_COMMAND_REMOVE_AUTOLOAD___OBSOLETE] = "REMOVE_AUTOLOAD (obsolete)",
     117                 :            :     [PA_COMMAND_GET_AUTOLOAD_INFO___OBSOLETE] = "GET_AUTOLOAD_INFO (obsolete)",
     118                 :            :     [PA_COMMAND_GET_AUTOLOAD_INFO_LIST___OBSOLETE] = "GET_AUTOLOAD_INFO_LIST (obsolete)",
     119                 :            : 
     120                 :            :     [PA_COMMAND_GET_RECORD_LATENCY] = "GET_RECORD_LATENCY",
     121                 :            :     [PA_COMMAND_CORK_RECORD_STREAM] = "CORK_RECORD_STREAM",
     122                 :            :     [PA_COMMAND_FLUSH_RECORD_STREAM] = "FLUSH_RECORD_STREAM",
     123                 :            :     [PA_COMMAND_PREBUF_PLAYBACK_STREAM] = "PREBUF_PLAYBACK_STREAM",
     124                 :            : 
     125                 :            :     /* SERVER->CLIENT */
     126                 :            :     [PA_COMMAND_REQUEST] = "REQUEST",
     127                 :            :     [PA_COMMAND_OVERFLOW] = "OVERFLOW",
     128                 :            :     [PA_COMMAND_UNDERFLOW] = "UNDERFLOW",
     129                 :            :     [PA_COMMAND_PLAYBACK_STREAM_KILLED] = "PLAYBACK_STREAM_KILLED",
     130                 :            :     [PA_COMMAND_RECORD_STREAM_KILLED] = "RECORD_STREAM_KILLED",
     131                 :            :     [PA_COMMAND_SUBSCRIBE_EVENT] = "SUBSCRIBE_EVENT",
     132                 :            : 
     133                 :            :     /* A few more client->server commands */
     134                 :            : 
     135                 :            :     /* Supported since protocol v10 (0.9.5) */
     136                 :            :     [PA_COMMAND_MOVE_SINK_INPUT] = "MOVE_SINK_INPUT",
     137                 :            :     [PA_COMMAND_MOVE_SOURCE_OUTPUT] = "MOVE_SOURCE_OUTPUT",
     138                 :            : 
     139                 :            :     /* Supported since protocol v11 (0.9.7) */
     140                 :            :     [PA_COMMAND_SET_SINK_INPUT_MUTE] = "SET_SINK_INPUT_MUTE",
     141                 :            : 
     142                 :            :     [PA_COMMAND_SUSPEND_SINK] = "SUSPEND_SINK",
     143                 :            :     [PA_COMMAND_SUSPEND_SOURCE] = "SUSPEND_SOURCE",
     144                 :            : 
     145                 :            :     /* Supported since protocol v12 (0.9.8) */
     146                 :            :     [PA_COMMAND_SET_PLAYBACK_STREAM_BUFFER_ATTR] = "SET_PLAYBACK_STREAM_BUFFER_ATTR",
     147                 :            :     [PA_COMMAND_SET_RECORD_STREAM_BUFFER_ATTR] = "SET_RECORD_STREAM_BUFFER_ATTR",
     148                 :            : 
     149                 :            :     [PA_COMMAND_UPDATE_PLAYBACK_STREAM_SAMPLE_RATE] = "UPDATE_PLAYBACK_STREAM_SAMPLE_RATE",
     150                 :            :     [PA_COMMAND_UPDATE_RECORD_STREAM_SAMPLE_RATE] = "UPDATE_RECORD_STREAM_SAMPLE_RATE",
     151                 :            : 
     152                 :            :     /* SERVER->CLIENT */
     153                 :            :     [PA_COMMAND_PLAYBACK_STREAM_SUSPENDED] = "PLAYBACK_STREAM_SUSPENDED",
     154                 :            :     [PA_COMMAND_RECORD_STREAM_SUSPENDED] = "RECORD_STREAM_SUSPENDED",
     155                 :            :     [PA_COMMAND_PLAYBACK_STREAM_MOVED] = "PLAYBACK_STREAM_MOVED",
     156                 :            :     [PA_COMMAND_RECORD_STREAM_MOVED] = "RECORD_STREAM_MOVED",
     157                 :            : 
     158                 :            :     /* Supported since protocol v13 (0.9.11) */
     159                 :            :     [PA_COMMAND_UPDATE_RECORD_STREAM_PROPLIST] = "UPDATE_RECORD_STREAM_PROPLIST",
     160                 :            :     [PA_COMMAND_UPDATE_PLAYBACK_STREAM_PROPLIST] = "UPDATE_RECORD_STREAM_PROPLIST",
     161                 :            :     [PA_COMMAND_UPDATE_CLIENT_PROPLIST] = "UPDATE_CLIENT_PROPLIST",
     162                 :            :     [PA_COMMAND_REMOVE_RECORD_STREAM_PROPLIST] = "REMOVE_RECORD_STREAM_PROPLIST",
     163                 :            :     [PA_COMMAND_REMOVE_PLAYBACK_STREAM_PROPLIST] = "REMOVE_PLAYBACK_STREAM_PROPLIST",
     164                 :            :     [PA_COMMAND_REMOVE_CLIENT_PROPLIST] = "REMOVE_CLIENT_PROPLIST",
     165                 :            : 
     166                 :            :     /* SERVER->CLIENT */
     167                 :            :     [PA_COMMAND_STARTED] = "STARTED",
     168                 :            : 
     169                 :            :     /* Supported since protocol v14 (0.9.12) */
     170                 :            :     [PA_COMMAND_EXTENSION] = "EXTENSION",
     171                 :            : 
     172                 :            :     /* Supported since protocol v15 (0.9.15) */
     173                 :            :     [PA_COMMAND_GET_CARD_INFO] = "GET_CARD_INFO",
     174                 :            :     [PA_COMMAND_GET_CARD_INFO_LIST] = "GET_CARD_INFO_LIST",
     175                 :            :     [PA_COMMAND_SET_CARD_PROFILE] = "SET_CARD_PROFILE",
     176                 :            : 
     177                 :            :     [PA_COMMAND_CLIENT_EVENT] = "GET_CLIENT_EVENT",
     178                 :            :     [PA_COMMAND_PLAYBACK_STREAM_EVENT] = "PLAYBACK_STREAM_EVENT",
     179                 :            :     [PA_COMMAND_RECORD_STREAM_EVENT] = "RECORD_STREAM_EVENT",
     180                 :            : 
     181                 :            :     /* SERVER->CLIENT */
     182                 :            :     [PA_COMMAND_PLAYBACK_BUFFER_ATTR_CHANGED] = "PLAYBACK_BUFFER_ATTR_CHANGED",
     183                 :            :     [PA_COMMAND_RECORD_BUFFER_ATTR_CHANGED] = "RECORD_BUFFER_ATTR_CHANGED",
     184                 :            : 
     185                 :            :     /* Supported since protocol v16 (0.9.16) */
     186                 :            :     [PA_COMMAND_SET_SINK_PORT] = "SET_SINK_PORT",
     187                 :            :     [PA_COMMAND_SET_SOURCE_PORT] = "SET_SOURCE_PORT",
     188                 :            : 
     189                 :            :     /* Supported since protocol v22 (1.0) */
     190                 :            :     [PA_COMMAND_SET_SOURCE_OUTPUT_VOLUME] = "SET_SOURCE_OUTPUT_VOLUME",
     191                 :            :     [PA_COMMAND_SET_SOURCE_OUTPUT_MUTE] = "SET_SOURCE_OUTPUT_MUTE",
     192                 :            : 
     193                 :            : };
     194                 :            : 
     195                 :            : #endif
     196                 :            : 
     197 [ -  + ][ #  # ]:         27 : PA_STATIC_FLIST_DECLARE(reply_infos, 0, pa_xfree);
     198                 :            : 
     199                 :            : struct reply_info {
     200                 :            :     pa_pdispatch *pdispatch;
     201                 :            :     PA_LLIST_FIELDS(struct reply_info);
     202                 :            :     pa_pdispatch_cb_t callback;
     203                 :            :     void *userdata;
     204                 :            :     pa_free_cb_t free_cb;
     205                 :            :     uint32_t tag;
     206                 :            :     pa_time_event *time_event;
     207                 :            : };
     208                 :            : 
     209                 :            : struct pa_pdispatch {
     210                 :            :     PA_REFCNT_DECLARE;
     211                 :            :     pa_mainloop_api *mainloop;
     212                 :            :     const pa_pdispatch_cb_t *callback_table;
     213                 :            :     unsigned n_commands;
     214                 :            :     PA_LLIST_HEAD(struct reply_info, replies);
     215                 :            :     pa_pdispatch_drain_cb_t drain_callback;
     216                 :            :     void *drain_userdata;
     217                 :            :     const pa_creds *creds;
     218                 :            :     pa_bool_t use_rtclock;
     219                 :            : };
     220                 :            : 
     221                 :          0 : static void reply_info_free(struct reply_info *r) {
     222         [ #  # ]:          0 :     pa_assert(r);
     223         [ #  # ]:          0 :     pa_assert(r->pdispatch);
     224         [ #  # ]:          0 :     pa_assert(r->pdispatch->mainloop);
     225                 :            : 
     226         [ #  # ]:          0 :     if (r->time_event)
     227                 :          0 :         r->pdispatch->mainloop->time_free(r->time_event);
     228                 :            : 
     229 [ #  # ][ #  # ]:          0 :     PA_LLIST_REMOVE(struct reply_info, r->pdispatch->replies, r);
         [ #  # ][ #  # ]
     230                 :            : 
     231         [ #  # ]:          0 :     if (pa_flist_push(PA_STATIC_FLIST_GET(reply_infos), r) < 0)
     232                 :          0 :         pa_xfree(r);
     233                 :          0 : }
     234                 :            : 
     235                 :          0 : pa_pdispatch* pa_pdispatch_new(pa_mainloop_api *mainloop, pa_bool_t use_rtclock, const pa_pdispatch_cb_t *table, unsigned entries) {
     236                 :            :     pa_pdispatch *pd;
     237                 :            : 
     238         [ #  # ]:          0 :     pa_assert(mainloop);
     239 [ #  # ][ #  # ]:          0 :     pa_assert((entries && table) || (!entries && !table));
     240                 :            : 
     241                 :          0 :     pd = pa_xnew0(pa_pdispatch, 1);
     242                 :          0 :     PA_REFCNT_INIT(pd);
     243                 :          0 :     pd->mainloop = mainloop;
     244                 :          0 :     pd->callback_table = table;
     245                 :          0 :     pd->n_commands = entries;
     246                 :          0 :     PA_LLIST_HEAD_INIT(struct reply_info, pd->replies);
     247                 :          0 :     pd->use_rtclock = use_rtclock;
     248                 :            : 
     249                 :          0 :     return pd;
     250                 :            : }
     251                 :            : 
     252                 :            : static void pdispatch_free(pa_pdispatch *pd) {
     253         [ #  # ]:          0 :     pa_assert(pd);
     254                 :            : 
     255         [ #  # ]:          0 :     while (pd->replies) {
     256         [ #  # ]:          0 :         if (pd->replies->free_cb)
     257                 :          0 :             pd->replies->free_cb(pd->replies->userdata);
     258                 :            : 
     259                 :          0 :         reply_info_free(pd->replies);
     260                 :            :     }
     261                 :            : 
     262                 :          0 :     pa_xfree(pd);
     263                 :            : }
     264                 :            : 
     265                 :          0 : static void run_action(pa_pdispatch *pd, struct reply_info *r, uint32_t command, pa_tagstruct *ts) {
     266                 :            :     pa_pdispatch_cb_t callback;
     267                 :            :     void *userdata;
     268                 :            :     uint32_t tag;
     269         [ #  # ]:          0 :     pa_assert(r);
     270                 :            : 
     271                 :          0 :     pa_pdispatch_ref(pd);
     272                 :            : 
     273                 :          0 :     callback = r->callback;
     274                 :          0 :     userdata = r->userdata;
     275                 :          0 :     tag = r->tag;
     276                 :            : 
     277                 :          0 :     reply_info_free(r);
     278                 :            : 
     279                 :          0 :     callback(pd, command, tag, ts, userdata);
     280                 :            : 
     281 [ #  # ][ #  # ]:          0 :     if (pd->drain_callback && !pa_pdispatch_is_pending(pd))
     282                 :          0 :         pd->drain_callback(pd, pd->drain_userdata);
     283                 :            : 
     284                 :          0 :     pa_pdispatch_unref(pd);
     285                 :          0 : }
     286                 :            : 
     287                 :          0 : int pa_pdispatch_run(pa_pdispatch *pd, pa_packet*packet, const pa_creds *creds, void *userdata) {
     288                 :            :     uint32_t tag, command;
     289                 :          0 :     pa_tagstruct *ts = NULL;
     290                 :          0 :     int ret = -1;
     291                 :            : 
     292         [ #  # ]:          0 :     pa_assert(pd);
     293         [ #  # ]:          0 :     pa_assert(PA_REFCNT_VALUE(pd) >= 1);
     294         [ #  # ]:          0 :     pa_assert(packet);
     295         [ #  # ]:          0 :     pa_assert(PA_REFCNT_VALUE(packet) >= 1);
     296         [ #  # ]:          0 :     pa_assert(packet->data);
     297                 :            : 
     298                 :          0 :     pa_pdispatch_ref(pd);
     299                 :            : 
     300         [ #  # ]:          0 :     if (packet->length <= 8)
     301                 :            :         goto finish;
     302                 :            : 
     303                 :          0 :     ts = pa_tagstruct_new(packet->data, packet->length);
     304                 :            : 
     305   [ #  #  #  # ]:          0 :     if (pa_tagstruct_getu32(ts, &command) < 0 ||
     306                 :          0 :         pa_tagstruct_getu32(ts, &tag) < 0)
     307                 :            :         goto finish;
     308                 :            : 
     309                 :            : #ifdef DEBUG_OPCODES
     310                 :            : {
     311                 :            :     char t[256];
     312                 :            :     char const *p = NULL;
     313                 :            : 
     314                 :            :     if (command >= PA_COMMAND_MAX || !(p = command_names[command]))
     315                 :            :         pa_snprintf((char*) (p = t), sizeof(t), "%u", command);
     316                 :            : 
     317                 :            :     pa_log("[%p] Received opcode <%s>", pd, p);
     318                 :            : }
     319                 :            : #endif
     320                 :            : 
     321                 :          0 :     pd->creds = creds;
     322                 :            : 
     323         [ #  # ]:          0 :     if (command == PA_COMMAND_ERROR || command == PA_COMMAND_REPLY) {
     324                 :            :         struct reply_info *r;
     325                 :            : 
     326         [ #  # ]:          0 :         PA_LLIST_FOREACH(r, pd->replies)
     327         [ #  # ]:          0 :             if (r->tag == tag)
     328                 :            :                 break;
     329                 :            : 
     330         [ #  # ]:          0 :         if (r)
     331                 :          0 :             run_action(pd, r, command, ts);
     332                 :            : 
     333 [ #  # ][ #  # ]:          0 :     } else if (pd->callback_table && (command < pd->n_commands) && pd->callback_table[command]) {
                 [ #  # ]
     334                 :          0 :         const pa_pdispatch_cb_t *cb = pd->callback_table+command;
     335                 :            : 
     336                 :          0 :         (*cb)(pd, command, tag, ts, userdata);
     337                 :            :     } else {
     338                 :          0 :         pa_log("Received unsupported command %u", command);
     339                 :          0 :         goto finish;
     340                 :            :     }
     341                 :            : 
     342                 :            :     ret = 0;
     343                 :            : 
     344                 :            : finish:
     345                 :          0 :     pd->creds = NULL;
     346                 :            : 
     347         [ #  # ]:          0 :     if (ts)
     348                 :          0 :         pa_tagstruct_free(ts);
     349                 :            : 
     350                 :          0 :     pa_pdispatch_unref(pd);
     351                 :            : 
     352                 :          0 :     return ret;
     353                 :            : }
     354                 :            : 
     355                 :          0 : static void timeout_callback(pa_mainloop_api*m, pa_time_event*e, const struct timeval *t, void *userdata) {
     356                 :          0 :     struct reply_info*r = userdata;
     357                 :            : 
     358         [ #  # ]:          0 :     pa_assert(r);
     359         [ #  # ]:          0 :     pa_assert(r->time_event == e);
     360         [ #  # ]:          0 :     pa_assert(r->pdispatch);
     361         [ #  # ]:          0 :     pa_assert(r->pdispatch->mainloop == m);
     362         [ #  # ]:          0 :     pa_assert(r->callback);
     363                 :            : 
     364                 :          0 :     run_action(r->pdispatch, r, PA_COMMAND_TIMEOUT, NULL);
     365                 :          0 : }
     366                 :            : 
     367                 :          0 : void pa_pdispatch_register_reply(pa_pdispatch *pd, uint32_t tag, int timeout, pa_pdispatch_cb_t cb, void *userdata, pa_free_cb_t free_cb) {
     368                 :            :     struct reply_info *r;
     369                 :            :     struct timeval tv;
     370                 :            : 
     371         [ #  # ]:          0 :     pa_assert(pd);
     372         [ #  # ]:          0 :     pa_assert(PA_REFCNT_VALUE(pd) >= 1);
     373         [ #  # ]:          0 :     pa_assert(cb);
     374                 :            : 
     375         [ #  # ]:          0 :     if (!(r = pa_flist_pop(PA_STATIC_FLIST_GET(reply_infos))))
     376                 :          0 :         r = pa_xnew(struct reply_info, 1);
     377                 :            : 
     378                 :          0 :     r->pdispatch = pd;
     379                 :          0 :     r->callback = cb;
     380                 :          0 :     r->userdata = userdata;
     381                 :          0 :     r->free_cb = free_cb;
     382                 :          0 :     r->tag = tag;
     383                 :            : 
     384         [ #  # ]:          0 :     pa_assert_se(r->time_event = pd->mainloop->time_new(pd->mainloop,
     385                 :            :                                                         pa_timeval_rtstore(&tv, pa_rtclock_now() + timeout * PA_USEC_PER_SEC, pd->use_rtclock),
     386                 :            :                                                         timeout_callback, r));
     387                 :            : 
     388 [ #  # ][ #  # ]:          0 :     PA_LLIST_PREPEND(struct reply_info, pd->replies, r);
     389                 :          0 : }
     390                 :            : 
     391                 :          0 : int pa_pdispatch_is_pending(pa_pdispatch *pd) {
     392         [ #  # ]:          0 :     pa_assert(pd);
     393         [ #  # ]:          0 :     pa_assert(PA_REFCNT_VALUE(pd) >= 1);
     394                 :            : 
     395                 :          0 :     return !!pd->replies;
     396                 :            : }
     397                 :            : 
     398                 :          0 : void pa_pdispatch_set_drain_callback(pa_pdispatch *pd, pa_pdispatch_drain_cb_t cb, void *userdata) {
     399         [ #  # ]:          0 :     pa_assert(pd);
     400         [ #  # ]:          0 :     pa_assert(PA_REFCNT_VALUE(pd) >= 1);
     401 [ #  # ][ #  # ]:          0 :     pa_assert(!cb || pa_pdispatch_is_pending(pd));
     402                 :            : 
     403                 :          0 :     pd->drain_callback = cb;
     404                 :          0 :     pd->drain_userdata = userdata;
     405                 :          0 : }
     406                 :            : 
     407                 :          0 : void pa_pdispatch_unregister_reply(pa_pdispatch *pd, void *userdata) {
     408                 :            :     struct reply_info *r, *n;
     409                 :            : 
     410         [ #  # ]:          0 :     pa_assert(pd);
     411         [ #  # ]:          0 :     pa_assert(PA_REFCNT_VALUE(pd) >= 1);
     412                 :            : 
     413         [ #  # ]:          0 :     PA_LLIST_FOREACH_SAFE(r, n, pd->replies)
     414         [ #  # ]:          0 :         if (r->userdata == userdata)
     415                 :          0 :             reply_info_free(r);
     416                 :          0 : }
     417                 :            : 
     418                 :          0 : void pa_pdispatch_unref(pa_pdispatch *pd) {
     419         [ #  # ]:          0 :     pa_assert(pd);
     420         [ #  # ]:          0 :     pa_assert(PA_REFCNT_VALUE(pd) >= 1);
     421                 :            : 
     422         [ #  # ]:          0 :     if (PA_REFCNT_DEC(pd) <= 0)
     423                 :            :         pdispatch_free(pd);
     424                 :          0 : }
     425                 :            : 
     426                 :          0 : pa_pdispatch* pa_pdispatch_ref(pa_pdispatch *pd) {
     427         [ #  # ]:          0 :     pa_assert(pd);
     428         [ #  # ]:          0 :     pa_assert(PA_REFCNT_VALUE(pd) >= 1);
     429                 :            : 
     430                 :          0 :     PA_REFCNT_INC(pd);
     431                 :          0 :     return pd;
     432                 :            : }
     433                 :            : 
     434                 :          0 : const pa_creds * pa_pdispatch_creds(pa_pdispatch *pd) {
     435         [ #  # ]:          0 :     pa_assert(pd);
     436         [ #  # ]:          0 :     pa_assert(PA_REFCNT_VALUE(pd) >= 1);
     437                 :            : 
     438                 :          0 :     return pd->creds;
     439                 :            : }

Generated by: LCOV version 1.9