[pulseaudio-discuss] [PATCH] Add support of callbacks for operation cancelation

Paul Meng mno2.csie at gmail.com
Fri Jan 4 20:41:15 PST 2013


Hi Tanu Kaskinen,

I rewrote the patch by following your feedback.
I kept "pa_operation_new_with_state_callback" ("
pa_operation_new_with_cancel_callback" previously) refactoring as the same
for a while because the argument favonia provided.
If you insist that we should remove pa_operation_new_with_state_callback,
I will send another patch with that removed.
Thanks




diff --git a/src/map-file b/src/map-file
index a20314c..91d61c2 100644
--- a/src/map-file
+++ b/src/map-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;
diff --git a/src/pulse/internal.h b/src/pulse/internal.h
index c5bdcb1..aee4398 100644
--- a/src/pulse/internal.h
+++ b/src/pulse/internal.h
@@ -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 */
 };
@@ -249,6 +251,7 @@ void pa_command_stream_event(pa_pdispatch *pd, uint32_t
command, uint32_t tag, p
 void pa_command_client_event(pa_pdispatch *pd, uint32_t command, uint32_t
tag, pa_tagstruct *t, void *userdata);
 void pa_command_stream_buffer_attr(pa_pdispatch *pd, uint32_t command,
uint32_t tag, pa_tagstruct *t, void *userdata);

+pa_operation *pa_operation_new_with_state_callback(pa_context *c,
pa_stream *s, pa_operation_cb_t callback, void *userdata,
pa_operation_notify_cb_t state_callback, void *state_userdata);
 pa_operation *pa_operation_new(pa_context *c, pa_stream *s,
pa_operation_cb_t callback, void *userdata);
 void pa_operation_done(pa_operation *o);

diff --git a/src/pulse/operation.c b/src/pulse/operation.c
index fe160a3..891269e 100644
--- a/src/pulse/operation.c
+++ b/src/pulse/operation.c
@@ -26,13 +26,14 @@
 #include <pulse/xmalloc.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/flist.h>
+#include <pulse/fork-detect.h>

 #include "internal.h"
 #include "operation.h"

 PA_STATIC_FLIST_DECLARE(operations, 0, pa_xfree);

-pa_operation *pa_operation_new(pa_context *c, pa_stream *s,
pa_operation_cb_t cb, void *userdata) {
+pa_operation *pa_operation_new_with_state_callback(pa_context *c,
pa_stream *s, pa_operation_cb_t cb, void *userdata,
pa_operation_notify_cb_t state_cb, void *state_userdata) {
     pa_operation *o;
     pa_assert(c);

@@ -47,6 +48,8 @@ pa_operation *pa_operation_new(pa_context *c, pa_stream
*s, pa_operation_cb_t cb
     o->state = PA_OPERATION_RUNNING;
     o->callback = cb;
     o->userdata = userdata;
+    o->state_callback = state_cb;
+    o->state_userdata = state_userdata;

     /* Refcounting is strictly one-way: from the "bigger" to the "smaller"
object. */
     PA_LLIST_PREPEND(pa_operation, c->operations, o);
@@ -55,6 +58,10 @@ pa_operation *pa_operation_new(pa_context *c, pa_stream
*s, pa_operation_cb_t cb
     return o;
 }

+pa_operation *pa_operation_new(pa_context *c, pa_stream *s,
pa_operation_cb_t cb, void *userdata) {
+    return pa_operation_new_with_state_callback(c, s, cb, userdata, NULL,
NULL);
+}
+
 pa_operation *pa_operation_ref(pa_operation *o) {
     pa_assert(o);
     pa_assert(PA_REFCNT_VALUE(o) >= 1);
@@ -91,6 +98,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 +113,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 +142,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;
+}
diff --git a/src/pulse/operation.h b/src/pulse/operation.h
index b6b5691..20c3636 100644
--- a/src/pulse/operation.h
+++ b/src/pulse/operation.h
@@ -34,6 +34,9 @@ PA_C_DECL_BEGIN
 /** An asynchronous operation object */
 typedef struct pa_operation pa_operation;

+/** A generic callback for operation cancelation */
+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 3.0 */
+void pa_operation_set_state_callback(pa_operation *o,
pa_operation_notify_cb_t cb, void *userdata);
+
 PA_C_DECL_END

 #endif


On Sat, Jan 5, 2013 at 12:25 AM, Favonia <favonia at gmail.com> wrote:

> On Fri, Jan 4, 2013 at 7:50 AM, Tanu Kaskinen <tanuk at iki.fi> wrote:
> > Ok, would you be willing to write an updated patch?
> I'm CC'ing one of my teammates who might be able to do it now.
>
> > Some feedback about the first version:
> >
> >  * It would be better to call the callback from operation_set_state
> > rather than from context_unlink().
> That's probably true. We'll look at it. Thanks.
>
> >  * pa_operation_new_with_cancel_callback() seems unnecessary. There's no
> > need to initialize the callback to anything else than NULL when creating
> > a new operation object.
> This is indeed unnecessary under the current practice. As far as I
> remember, all current APIs which return a new pa_operation object only
> provide a way to subscribe to the result of successful execution.
> Perhaps I was hoping that, in some future version we can also set up
> the new callback when created. We can certainly comment out this
> function for now. However, in the long run, refactoring with this
> function will help, I think.
>
> >  * Every new function in the public API need to be added to
> > src/map-file, otherwise applications won't be able to use the function
> > (linking will fail).
> I see. Sorry for the mistake.
>
> Favonia
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/pulseaudio-discuss/attachments/20130105/f777b45c/attachment-0001.html>


More information about the pulseaudio-discuss mailing list