source: roaraudio/libroarpulse/mainloop-signal.c @ 3496:474e67abcc4e

Last change on this file since 3496:474e67abcc4e was 3496:474e67abcc4e, checked in by phi, 10 years ago

fix a small bug with uninited memory

File size: 4.8 KB
Line 
1//mainloop-signal.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010
5 *  The code (may) include prototypes and comments (and maybe
6 *  other code fragements) from libpulse*. They are mostly copyrighted by:
7 *  Lennart Poettering <poettering@users.sourceforge.net> and
8 *  Pierre Ossman <drzeus@drzeus.cx>
9 *
10 *  This file is part of libroarpulse a part of RoarAudio,
11 *  a cross-platform sound system for both, home and professional use.
12 *  See README for details.
13 *
14 *  This file is free software; you can redistribute it and/or modify
15 *  it under the terms of the GNU General Public License version 3
16 *  as published by the Free Software Foundation.
17 *
18 *  RoarAudio is distributed in the hope that it will be useful,
19 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
20 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 *  GNU General Public License for more details.
22 *
23 *  You should have received a copy of the GNU General Public License
24 *  along with this software; see the file COPYING.  If not, write to
25 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
26 *
27 *  NOTE for everyone want's to change something and send patches:
28 *  read README and HACKING! There a addition information on
29 *  the license of this document you need to read before you send
30 *  any patches.
31 *
32 *  NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc
33 *  or libpulse*:
34 *  The libs libroaresd, libroararts and libroarpulse link this libroar
35 *  and are therefore GPL. Because of this it may be illigal to use
36 *  them with any software that uses libesd, libartsc or libpulse*.
37 */
38
39#include <libroarpulse/libroarpulse.h>
40
41#define MAX_SIG 64 /* there is no way to find out */
42
43typedef void (*pa_signal_cb_t) (pa_mainloop_api *api, pa_signal_event*e, int sig, void *userdata);
44
45struct pa_signal_event {
46 int used;
47 int sig;
48 pa_signal_cb_t cb;
49 void * userdata;
50};
51
52static int _roar_pa_signal_inited = 0;
53
54static struct {
55 pa_mainloop_api * api;
56 pa_signal_event sig[MAX_SIG];
57#ifdef ROAR_HAVE_PIPE
58 int pipefh[2];
59 pa_io_event * io_event;
60#endif
61} _roar_pa_signal;
62
63static void _roar_pa_signal_iocb(
64#ifndef ROAR_HAVE_PIPE
65                                 int                 sig
66#else
67                                 pa_mainloop_api   * a,
68                                 pa_io_event       * e,
69                                 int                 fd,
70                                 pa_io_event_flags_t f,
71                                 void *userdata
72#endif
73                                ) {
74 pa_signal_event * se;
75#ifdef ROAR_HAVE_PIPE
76 int sig;
77 size_t ret;
78
79 ret = read(fd, &sig, sizeof(sig));
80
81 if ( ret != sizeof(sig) )
82  return;
83#endif
84
85 if ( sig >= MAX_SIG )
86  return;
87
88 se = &(_roar_pa_signal.sig[sig]);
89
90 if ( !se->used )
91  return;
92
93 ROAR_DBG("_roar_pa_signal_iocb(*): sig=%s(%i), se->cb=%p", strsignal(sig), sig, se->cb);
94
95 if ( se->cb != NULL )
96  se->cb(_roar_pa_signal.api, se, sig, se->userdata);
97}
98
99static void _roar_pa_signal_handler (int sig) {
100#ifdef ROAR_HAVE_PIPE
101 write(_roar_pa_signal.pipefh[1], &sig, sizeof(sig));
102#else
103 _roar_pa_signal_iocb(sig);
104#endif
105}
106
107/** Initialize the UNIX signal subsystem and bind it to the specified main loop */
108int pa_signal_init(pa_mainloop_api *api) {
109
110 if ( _roar_pa_signal_inited )
111  return -1;
112
113 memset(&_roar_pa_signal, 0, sizeof(_roar_pa_signal));
114
115 _roar_pa_signal.api = api;
116
117#ifdef ROAR_HAVE_PIPE
118 if ( pipe(_roar_pa_signal.pipefh) == -1 )
119  return -1;
120
121 _roar_pa_signal.io_event = api->io_new(api, _roar_pa_signal.pipefh[0], PA_IO_EVENT_INPUT, _roar_pa_signal_iocb, NULL);
122#endif
123
124 _roar_pa_signal_inited = 1;
125
126 return 0;
127}
128
129/** Cleanup the signal subsystem */
130void pa_signal_done(void) {
131 int i;
132
133 for (i = 0; i < MAX_SIG; i++) {
134  _roar_pa_signal.sig[i].used = 0;
135 }
136
137#ifdef ROAR_HAVE_PIPE
138 _roar_pa_signal.api->io_free(_roar_pa_signal.io_event);
139#endif
140
141 _roar_pa_signal_inited = 0;
142}
143
144/** Create a new UNIX signal event source object */
145pa_signal_event* pa_signal_new(int sig, pa_signal_cb_t callback, void *userdata) {
146 if ( !_roar_pa_signal_inited )
147  return NULL;
148
149 if ( sig >= MAX_SIG )
150  return NULL;
151
152 _roar_pa_signal.sig[sig].used     = 1;
153 _roar_pa_signal.sig[sig].sig      = sig;
154 _roar_pa_signal.sig[sig].cb       = callback;
155 _roar_pa_signal.sig[sig].userdata = userdata;
156
157 signal(sig, _roar_pa_signal_handler);
158
159 return &(_roar_pa_signal.sig[sig]);
160}
161
162/** Free a UNIX signal event source object */
163void pa_signal_free(pa_signal_event *e) {
164 if ( !_roar_pa_signal_inited )
165  return;
166
167 if ( e == NULL )
168  return;
169
170 signal(e->sig, SIG_DFL);
171
172 e->used = 0;
173}
174
175/** Set a function that is called when the signal event source is destroyed. Use this to free the userdata argument if required */
176void pa_signal_set_destroy(pa_signal_event *e, void (*callback) (pa_mainloop_api *api, pa_signal_event*e, void *userdata));
177
178//ll
Note: See TracBrowser for help on using the repository browser.