]> code.delx.au - pulseaudio/commitdiff
pulse: Add pa_operation_set_state_callback() API
authorPaul Meng <mno2.csie@gmail.com>
Mon, 7 Jan 2013 13:41:26 +0000 (21:41 +0800)
committerTanu Kaskinen <tanuk@iki.fi>
Sat, 12 Jan 2013 15:55:07 +0000 (17:55 +0200)
[The original commit message didn't have any explanation why this
change is made, so I'll add that information here myself.
--Tanu Kaskinen]

This change is from the developers of a Haskell binding[1]. According
to them, this change isn't strictly necessary, but their code gets
significantly cleaner if they can register an operation callback that
is called when the operation is cancelled due to the context getting
disconnected.

[1] https://github.com/favonia/pulse

src/map-file
src/pulse/internal.h
src/pulse/operation.c
src/pulse/operation.h

index a20314c248f86a826c69bbf0c7e31c26756bfd77..91d61c23dbad237cfc51eb9565b92a1b8e1d0921 100644 (file)
@@ -220,6 +220,7 @@ pa_msleep;
 pa_operation_cancel;
 pa_operation_get_state;
 pa_operation_ref;
+pa_operation_set_state_callback;
 pa_operation_unref;
 pa_parse_sample_format;
 pa_path_get_filename;
index c5bdcb1efb7e5df05ff5e01bc80cac1deae3f499..833653df0d6606c281d67d255bdea76960144755 100644 (file)
@@ -234,6 +234,8 @@ struct pa_operation {
     pa_operation_state_t state;
     void *userdata;
     pa_operation_cb_t callback;
+    void *state_userdata;
+    pa_operation_notify_cb_t state_callback;
 
     void *private; /* some operations might need this */
 };
index fe160a3c74ef7e0d786f70bfd36c0e675cc6213a..8fdbea71ded639a72c5bb793eac100d9048b84a1 100644 (file)
@@ -26,6 +26,7 @@
 #include <pulse/xmalloc.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/flist.h>
+#include <pulse/fork-detect.h>
 
 #include "internal.h"
 #include "operation.h"
@@ -91,6 +92,8 @@ static void operation_unlink(pa_operation *o) {
     o->stream = NULL;
     o->callback = NULL;
     o->userdata = NULL;
+    o->state_callback = NULL;
+    o->state_userdata = NULL;
 }
 
 static void operation_set_state(pa_operation *o, pa_operation_state_t st) {
@@ -104,6 +107,9 @@ static void operation_set_state(pa_operation *o, pa_operation_state_t st) {
 
     o->state = st;
 
+    if (o->state_callback)
+        o->state_callback(o, o->state_userdata);
+
     if ((o->state == PA_OPERATION_DONE) || (o->state == PA_OPERATION_CANCELED))
         operation_unlink(o);
 
@@ -130,3 +136,17 @@ pa_operation_state_t pa_operation_get_state(pa_operation *o) {
 
     return o->state;
 }
+
+void pa_operation_set_state_callback(pa_operation *o, pa_operation_notify_cb_t cb, void *userdata) {
+    pa_assert(o);
+    pa_assert(PA_REFCNT_VALUE(o) >= 1);
+
+    if (pa_detect_fork())
+        return;
+
+    if (o->state == PA_OPERATION_DONE || o->state == PA_OPERATION_CANCELED)
+        return;
+
+    o->state_callback = cb;
+    o->state_userdata = userdata;
+}
index b6b5691d2bff1a74efa1c7203ad1a9465e79b022..4d5aa2be9c7cf908724623d2fe2377a87d43c40d 100644 (file)
@@ -34,6 +34,9 @@ PA_C_DECL_BEGIN
 /** An asynchronous operation object */
 typedef struct pa_operation pa_operation;
 
+/** A callback for operation state changes */
+typedef void (*pa_operation_notify_cb_t) (pa_operation *o, void *userdata);
+
 /** Increase the reference count by one */
 pa_operation *pa_operation_ref(pa_operation *o);
 
@@ -50,6 +53,10 @@ void pa_operation_cancel(pa_operation *o);
 /** Return the current status of the operation */
 pa_operation_state_t pa_operation_get_state(pa_operation *o);
 
+/** Set the callback function that is called when the operation
+ * is canceled due to disconnection. \since 4.0 */
+void pa_operation_set_state_callback(pa_operation *o, pa_operation_notify_cb_t cb, void *userdata);
+
 PA_C_DECL_END
 
 #endif