LCOV - code coverage report
Current view: top level - pulsecore - core.c (source / functions) Hit Total Coverage
Test: lcov.out Lines: 0 147 0.0 %
Date: 2012-07-17 Functions: 0 10 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 88 0.0 %

           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 published
       9                 :            :   by the Free Software Foundation; either version 2.1 of the License,
      10                 :            :   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                 :            :   General Public License for more details.
      16                 :            : 
      17                 :            :   You should have received a copy of the GNU Lesser General Public License
      18                 :            :   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 <stdlib.h>
      28                 :            : #include <stdio.h>
      29                 :            : #include <signal.h>
      30                 :            : 
      31                 :            : #include <pulse/rtclock.h>
      32                 :            : #include <pulse/timeval.h>
      33                 :            : #include <pulse/xmalloc.h>
      34                 :            : 
      35                 :            : #include <pulsecore/module.h>
      36                 :            : #include <pulsecore/core-rtclock.h>
      37                 :            : #include <pulsecore/core-util.h>
      38                 :            : #include <pulsecore/core-scache.h>
      39                 :            : #include <pulsecore/core-subscribe.h>
      40                 :            : #include <pulsecore/random.h>
      41                 :            : #include <pulsecore/log.h>
      42                 :            : #include <pulsecore/macro.h>
      43                 :            : 
      44                 :            : #include "core.h"
      45                 :            : 
      46         [ #  # ]:          0 : PA_DEFINE_PUBLIC_CLASS(pa_core, pa_msgobject);
      47                 :            : 
      48                 :          0 : static int core_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {
      49                 :          0 :     pa_core *c = PA_CORE(o);
      50                 :            : 
      51                 :            :     pa_core_assert_ref(c);
      52                 :            : 
      53         [ #  # ]:          0 :     switch (code) {
      54                 :            : 
      55                 :            :         case PA_CORE_MESSAGE_UNLOAD_MODULE:
      56                 :          0 :             pa_module_unload(c, userdata, TRUE);
      57                 :          0 :             return 0;
      58                 :            : 
      59                 :            :         default:
      60                 :            :             return -1;
      61                 :            :     }
      62                 :            : }
      63                 :            : 
      64                 :            : static void core_free(pa_object *o);
      65                 :            : 
      66                 :          0 : pa_core* pa_core_new(pa_mainloop_api *m, pa_bool_t shared, size_t shm_size) {
      67                 :            :     pa_core* c;
      68                 :            :     pa_mempool *pool;
      69                 :            :     int j;
      70                 :            : 
      71         [ #  # ]:          0 :     pa_assert(m);
      72                 :            : 
      73         [ #  # ]:          0 :     if (shared) {
      74         [ #  # ]:          0 :         if (!(pool = pa_mempool_new(shared, shm_size))) {
      75                 :          0 :             pa_log_warn("failed to allocate shared memory pool. Falling back to a normal memory pool.");
      76                 :          0 :             shared = FALSE;
      77                 :            :         }
      78                 :            :     }
      79                 :            : 
      80         [ #  # ]:          0 :     if (!shared) {
      81         [ #  # ]:          0 :         if (!(pool = pa_mempool_new(shared, shm_size))) {
      82                 :          0 :             pa_log("pa_mempool_new() failed.");
      83                 :          0 :             return NULL;
      84                 :            :         }
      85                 :            :     }
      86                 :            : 
      87                 :          0 :     c = pa_msgobject_new(pa_core);
      88                 :          0 :     c->parent.parent.free = core_free;
      89                 :          0 :     c->parent.process_msg = core_process_msg;
      90                 :            : 
      91                 :          0 :     c->state = PA_CORE_STARTUP;
      92                 :          0 :     c->mainloop = m;
      93                 :            : 
      94                 :          0 :     c->clients = pa_idxset_new(NULL, NULL);
      95                 :          0 :     c->cards = pa_idxset_new(NULL, NULL);
      96                 :          0 :     c->sinks = pa_idxset_new(NULL, NULL);
      97                 :          0 :     c->sources = pa_idxset_new(NULL, NULL);
      98                 :          0 :     c->sink_inputs = pa_idxset_new(NULL, NULL);
      99                 :          0 :     c->source_outputs = pa_idxset_new(NULL, NULL);
     100                 :          0 :     c->modules = pa_idxset_new(NULL, NULL);
     101                 :          0 :     c->scache = pa_idxset_new(NULL, NULL);
     102                 :            : 
     103                 :          0 :     c->namereg = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
     104                 :          0 :     c->shared = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
     105                 :            : 
     106                 :          0 :     c->default_source = NULL;
     107                 :          0 :     c->default_sink = NULL;
     108                 :            : 
     109                 :          0 :     c->default_sample_spec.format = PA_SAMPLE_S16NE;
     110                 :          0 :     c->default_sample_spec.rate = 44100;
     111                 :          0 :     c->default_sample_spec.channels = 2;
     112                 :          0 :     pa_channel_map_init_extend(&c->default_channel_map, c->default_sample_spec.channels, PA_CHANNEL_MAP_DEFAULT);
     113                 :          0 :     c->default_n_fragments = 4;
     114                 :          0 :     c->default_fragment_size_msec = 25;
     115                 :            : 
     116                 :          0 :     c->deferred_volume_safety_margin_usec = 8000;
     117                 :          0 :     c->deferred_volume_extra_delay_usec = 0;
     118                 :            : 
     119                 :          0 :     c->module_defer_unload_event = NULL;
     120                 :          0 :     c->scache_auto_unload_event = NULL;
     121                 :            : 
     122                 :          0 :     c->subscription_defer_event = NULL;
     123                 :          0 :     PA_LLIST_HEAD_INIT(pa_subscription, c->subscriptions);
     124                 :          0 :     PA_LLIST_HEAD_INIT(pa_subscription_event, c->subscription_event_queue);
     125                 :          0 :     c->subscription_event_last = NULL;
     126                 :            : 
     127                 :          0 :     c->mempool = pool;
     128                 :          0 :     pa_silence_cache_init(&c->silence_cache);
     129                 :            : 
     130                 :          0 :     c->exit_event = NULL;
     131                 :            : 
     132                 :          0 :     c->exit_idle_time = -1;
     133                 :          0 :     c->scache_idle_time = 20;
     134                 :            : 
     135                 :          0 :     c->flat_volumes = TRUE;
     136                 :          0 :     c->disallow_module_loading = FALSE;
     137                 :          0 :     c->disallow_exit = FALSE;
     138                 :          0 :     c->running_as_daemon = FALSE;
     139                 :          0 :     c->realtime_scheduling = FALSE;
     140                 :          0 :     c->realtime_priority = 5;
     141                 :          0 :     c->disable_remixing = FALSE;
     142                 :          0 :     c->disable_lfe_remixing = FALSE;
     143                 :          0 :     c->deferred_volume = TRUE;
     144                 :          0 :     c->resample_method = PA_RESAMPLER_SPEEX_FLOAT_BASE + 3;
     145                 :            : 
     146         [ #  # ]:          0 :     for (j = 0; j < PA_CORE_HOOK_MAX; j++)
     147                 :          0 :         pa_hook_init(&c->hooks[j], c);
     148                 :            : 
     149                 :          0 :     pa_random(&c->cookie, sizeof(c->cookie));
     150                 :            : 
     151                 :            : #ifdef SIGPIPE
     152                 :          0 :     pa_check_signal_is_blocked(SIGPIPE);
     153                 :            : #endif
     154                 :            : 
     155                 :          0 :     pa_core_check_idle(c);
     156                 :            : 
     157                 :          0 :     c->state = PA_CORE_RUNNING;
     158                 :            : 
     159                 :          0 :     return c;
     160                 :            : }
     161                 :            : 
     162                 :          0 : static void core_free(pa_object *o) {
     163                 :          0 :     pa_core *c = PA_CORE(o);
     164                 :            :     int j;
     165         [ #  # ]:          0 :     pa_assert(c);
     166                 :            : 
     167                 :          0 :     c->state = PA_CORE_SHUTDOWN;
     168                 :            : 
     169                 :            :     /* Note: All modules and samples in the cache should be unloaded before
     170                 :            :      * we get here */
     171                 :            : 
     172         [ #  # ]:          0 :     pa_assert(pa_idxset_isempty(c->scache));
     173                 :          0 :     pa_idxset_free(c->scache, NULL, NULL);
     174                 :            : 
     175         [ #  # ]:          0 :     pa_assert(pa_idxset_isempty(c->modules));
     176                 :          0 :     pa_idxset_free(c->modules, NULL, NULL);
     177                 :            : 
     178         [ #  # ]:          0 :     pa_assert(pa_idxset_isempty(c->clients));
     179                 :          0 :     pa_idxset_free(c->clients, NULL, NULL);
     180                 :            : 
     181         [ #  # ]:          0 :     pa_assert(pa_idxset_isempty(c->cards));
     182                 :          0 :     pa_idxset_free(c->cards, NULL, NULL);
     183                 :            : 
     184         [ #  # ]:          0 :     pa_assert(pa_idxset_isempty(c->sinks));
     185                 :          0 :     pa_idxset_free(c->sinks, NULL, NULL);
     186                 :            : 
     187         [ #  # ]:          0 :     pa_assert(pa_idxset_isempty(c->sources));
     188                 :          0 :     pa_idxset_free(c->sources, NULL, NULL);
     189                 :            : 
     190         [ #  # ]:          0 :     pa_assert(pa_idxset_isempty(c->source_outputs));
     191                 :          0 :     pa_idxset_free(c->source_outputs, NULL, NULL);
     192                 :            : 
     193         [ #  # ]:          0 :     pa_assert(pa_idxset_isempty(c->sink_inputs));
     194                 :          0 :     pa_idxset_free(c->sink_inputs, NULL, NULL);
     195                 :            : 
     196         [ #  # ]:          0 :     pa_assert(pa_hashmap_isempty(c->namereg));
     197                 :          0 :     pa_hashmap_free(c->namereg, NULL, NULL);
     198                 :            : 
     199         [ #  # ]:          0 :     pa_assert(pa_hashmap_isempty(c->shared));
     200                 :          0 :     pa_hashmap_free(c->shared, NULL, NULL);
     201                 :            : 
     202                 :          0 :     pa_subscription_free_all(c);
     203                 :            : 
     204         [ #  # ]:          0 :     if (c->exit_event)
     205                 :          0 :         c->mainloop->time_free(c->exit_event);
     206                 :            : 
     207         [ #  # ]:          0 :     pa_assert(!c->default_source);
     208         [ #  # ]:          0 :     pa_assert(!c->default_sink);
     209                 :            : 
     210                 :          0 :     pa_silence_cache_done(&c->silence_cache);
     211                 :          0 :     pa_mempool_free(c->mempool);
     212                 :            : 
     213         [ #  # ]:          0 :     for (j = 0; j < PA_CORE_HOOK_MAX; j++)
     214                 :          0 :         pa_hook_done(&c->hooks[j]);
     215                 :            : 
     216                 :          0 :     pa_xfree(c);
     217                 :          0 : }
     218                 :            : 
     219                 :          0 : static void exit_callback(pa_mainloop_api *m, pa_time_event *e, const struct timeval *t, void *userdata) {
     220                 :          0 :     pa_core *c = userdata;
     221         [ #  # ]:          0 :     pa_assert(c->exit_event == e);
     222                 :            : 
     223                 :          0 :     pa_log_info("We are idle, quitting...");
     224                 :          0 :     pa_core_exit(c, TRUE, 0);
     225                 :          0 : }
     226                 :            : 
     227                 :          0 : void pa_core_check_idle(pa_core *c) {
     228         [ #  # ]:          0 :     pa_assert(c);
     229                 :            : 
     230 [ #  # ][ #  # ]:          0 :     if (!c->exit_event &&
     231         [ #  # ]:          0 :         c->exit_idle_time >= 0 &&
     232                 :          0 :         pa_idxset_size(c->clients) == 0) {
     233                 :            : 
     234                 :          0 :         c->exit_event = pa_core_rttime_new(c, pa_rtclock_now() + c->exit_idle_time * PA_USEC_PER_SEC, exit_callback, c);
     235                 :            : 
     236 [ #  # ][ #  # ]:          0 :     } else if (c->exit_event && pa_idxset_size(c->clients) > 0) {
     237                 :          0 :         c->mainloop->time_free(c->exit_event);
     238                 :          0 :         c->exit_event = NULL;
     239                 :            :     }
     240                 :          0 : }
     241                 :            : 
     242                 :          0 : int pa_core_exit(pa_core *c, pa_bool_t force, int retval) {
     243         [ #  # ]:          0 :     pa_assert(c);
     244                 :            : 
     245 [ #  # ][ #  # ]:          0 :     if (c->disallow_exit && !force)
     246                 :            :         return -1;
     247                 :            : 
     248                 :          0 :     c->mainloop->quit(c->mainloop, retval);
     249                 :          0 :     return 0;
     250                 :            : }
     251                 :            : 
     252                 :          0 : void pa_core_maybe_vacuum(pa_core *c) {
     253         [ #  # ]:          0 :     pa_assert(c);
     254                 :            : 
     255 [ #  # ][ #  # ]:          0 :     if (pa_idxset_isempty(c->sink_inputs) && pa_idxset_isempty(c->source_outputs)) {
     256                 :          0 :         pa_log_debug("Hmm, no streams around, trying to vacuum.");
     257                 :          0 :         pa_mempool_vacuum(c->mempool);
     258                 :            :     } else {
     259                 :            :         pa_sink *si;
     260                 :            :         pa_source *so;
     261                 :            :         uint32_t idx;
     262                 :            : 
     263                 :          0 :         idx = 0;
     264         [ #  # ]:          0 :         PA_IDXSET_FOREACH(si, c->sinks, idx)
     265         [ #  # ]:          0 :             if (pa_sink_get_state(si) != PA_SINK_SUSPENDED)
     266                 :            :                 return;
     267                 :            : 
     268                 :          0 :         idx = 0;
     269         [ #  # ]:          0 :         PA_IDXSET_FOREACH(so, c->sources, idx)
     270         [ #  # ]:          0 :             if (pa_source_get_state(so) != PA_SOURCE_SUSPENDED)
     271                 :            :                 return;
     272                 :            : 
     273                 :          0 :         pa_log_info("All sinks and sources are suspended, vacuuming memory");
     274                 :          0 :         pa_mempool_vacuum(c->mempool);
     275                 :            :     }
     276                 :            : }
     277                 :            : 
     278                 :          0 : pa_time_event* pa_core_rttime_new(pa_core *c, pa_usec_t usec, pa_time_event_cb_t cb, void *userdata) {
     279                 :            :     struct timeval tv;
     280                 :            : 
     281         [ #  # ]:          0 :     pa_assert(c);
     282         [ #  # ]:          0 :     pa_assert(c->mainloop);
     283                 :            : 
     284                 :          0 :     return c->mainloop->time_new(c->mainloop, pa_timeval_rtstore(&tv, usec, TRUE), cb, userdata);
     285                 :            : }
     286                 :            : 
     287                 :          0 : void pa_core_rttime_restart(pa_core *c, pa_time_event *e, pa_usec_t usec) {
     288                 :            :     struct timeval tv;
     289                 :            : 
     290         [ #  # ]:          0 :     pa_assert(c);
     291         [ #  # ]:          0 :     pa_assert(c->mainloop);
     292                 :            : 
     293                 :          0 :     c->mainloop->time_restart(e, pa_timeval_rtstore(&tv, usec, TRUE));
     294                 :          0 : }

Generated by: LCOV version 1.9