source: roaraudio/libroarpulse/mainloop-signal.c @ 3480:4e3826267412

Last change on this file since 3480:4e3826267412 was 3480:4e3826267412, checked in by phi, 14 years ago

use IO based indirect callbacks

File size: 4.4 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 int pipefh[2];
58 pa_io_event * io_event;
59} _roar_pa_signal;
60
61static void _roar_pa_signal_handler (int sig) {
62 write(_roar_pa_signal.pipefh[1], &sig, sizeof(sig));
63}
64
65static void _roar_pa_signal_iocb(pa_mainloop_api   * a,
66                                 pa_io_event       * e,
67                                 int                 fd,
68                                 pa_io_event_flags_t f,
69                                 void *userdata         ) {
70 pa_signal_event * se;
71 int sig;
72 size_t ret;
73
74 ret = read(fd, &sig, sizeof(sig));
75
76 if ( ret != sizeof(sig) )
77  return;
78
79 if ( sig >= MAX_SIG )
80  return;
81
82 se = &(_roar_pa_signal.sig[sig]);
83
84 if ( !se->used )
85  return;
86
87 if ( se->cb != NULL )
88  se->cb(_roar_pa_signal.api, se, sig, se->userdata);
89}
90
91/** Initialize the UNIX signal subsystem and bind it to the specified main loop */
92int pa_signal_init(pa_mainloop_api *api) {
93
94 if ( _roar_pa_signal_inited )
95  return -1;
96
97 memset(&_roar_pa_signal, 0, sizeof(_roar_pa_signal));
98
99 _roar_pa_signal.api = api;
100
101 if ( pipe(_roar_pa_signal.pipefh) == -1 )
102  return -1;
103
104 _roar_pa_signal.io_event = api->io_new(api, _roar_pa_signal.pipefh[0], PA_IO_EVENT_INPUT, _roar_pa_signal_iocb, NULL);
105
106 _roar_pa_signal_inited = 1;
107
108 return 0;
109}
110
111/** Cleanup the signal subsystem */
112void pa_signal_done(void) {
113 int i;
114
115 for (i = 0; i < MAX_SIG; i++) {
116  _roar_pa_signal.sig[i].used = 0;
117 }
118
119 _roar_pa_signal.api->io_free(_roar_pa_signal.io_event);
120
121 _roar_pa_signal_inited = 0;
122}
123
124/** Create a new UNIX signal event source object */
125pa_signal_event* pa_signal_new(int sig, pa_signal_cb_t callback, void *userdata) {
126 if ( !_roar_pa_signal_inited )
127  return NULL;
128
129 if ( sig >= MAX_SIG )
130  return NULL;
131
132 _roar_pa_signal.sig[sig].used     = 1;
133 _roar_pa_signal.sig[sig].sig      = sig;
134 _roar_pa_signal.sig[sig].cb       = callback;
135 _roar_pa_signal.sig[sig].userdata = userdata;
136
137 signal(sig, _roar_pa_signal_handler);
138
139 return &(_roar_pa_signal.sig[sig]);
140}
141
142/** Free a UNIX signal event source object */
143void pa_signal_free(pa_signal_event *e) {
144 if ( !_roar_pa_signal_inited )
145  return;
146
147 if ( e == NULL )
148  return;
149
150 signal(e->sig, SIG_DFL);
151
152 e->used = 0;
153}
154
155/** Set a function that is called when the signal event source is destroyed. Use this to free the userdata argument if required */
156void pa_signal_set_destroy(pa_signal_event *e, void (*callback) (pa_mainloop_api *api, pa_signal_event*e, void *userdata));
157
158//ll
Note: See TracBrowser for help on using the repository browser.