]> code.delx.au - pulseaudio/blob - src/pulse/operation.c
f23def50c24158e51f55c9d04824449c0d32234c
[pulseaudio] / src / pulse / operation.c
1 /* $Id$ */
2
3 /***
4 This file is part of PulseAudio.
5
6 Copyright 2004-2006 Lennart Poettering
7
8 PulseAudio is free software; you can redistribute it and/or modify
9 it under the terms of the GNU Lesser General Public License as published
10 by the Free Software Foundation; either version 2 of the License,
11 or (at your option) any later version.
12
13 PulseAudio is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with PulseAudio; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21 USA.
22 ***/
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <assert.h>
29
30 #include <pulse/xmalloc.h>
31
32 #include "internal.h"
33 #include "operation.h"
34
35 pa_operation *pa_operation_new(pa_context *c, pa_stream *s, pa_operation_cb_t cb, void *userdata) {
36 pa_operation *o;
37 assert(c);
38
39 o = pa_xnew(pa_operation, 1);
40 o->ref = 1;
41 o->context = c;
42 o->stream = s;
43
44 o->state = PA_OPERATION_RUNNING;
45 o->callback = cb;
46 o->userdata = userdata;
47
48 /* Refcounting is strictly one-way: from the "bigger" to the "smaller" object. */
49 PA_LLIST_PREPEND(pa_operation, c->operations, o);
50 pa_operation_ref(o);
51
52 return o;
53 }
54
55 pa_operation *pa_operation_ref(pa_operation *o) {
56 assert(o);
57 assert(o->ref >= 1);
58
59 o->ref++;
60 return o;
61 }
62
63 void pa_operation_unref(pa_operation *o) {
64 assert(o);
65 assert(o->ref >= 1);
66
67 if ((--(o->ref)) == 0) {
68 assert(!o->context);
69 assert(!o->stream);
70 pa_xfree(o);
71 }
72 }
73
74 static void operation_set_state(pa_operation *o, pa_operation_state_t st) {
75 assert(o);
76 assert(o->ref >= 1);
77
78 if (st == o->state)
79 return;
80
81 pa_operation_ref(o);
82
83 o->state = st;
84
85 if ((o->state == PA_OPERATION_DONE) || (o->state == PA_OPERATION_CANCELED)) {
86
87 if (o->context) {
88 assert(o->ref >= 2);
89
90 PA_LLIST_REMOVE(pa_operation, o->context->operations, o);
91 pa_operation_unref(o);
92 }
93
94 o->context = NULL;
95 o->stream = NULL;
96 o->callback = NULL;
97 o->userdata = NULL;
98 }
99
100 pa_operation_unref(o);
101 }
102
103 void pa_operation_cancel(pa_operation *o) {
104 assert(o);
105 assert(o->ref >= 1);
106
107 operation_set_state(o, PA_OPERATION_CANCELED);
108 }
109
110 void pa_operation_done(pa_operation *o) {
111 assert(o);
112 assert(o->ref >= 1);
113
114 operation_set_state(o, PA_OPERATION_DONE);
115 }
116
117 pa_operation_state_t pa_operation_get_state(pa_operation *o) {
118 assert(o);
119 assert(o->ref >= 1);
120
121 return o->state;
122 }