Skip to content

Commit 211946c

Browse files
Sync handler concurrency and docs issues.
Move sync handler to volatile field - potential concurrency issue. Add missing Javadoc for sync handler methods. Add a clearSyncHandler convenience method.
1 parent e50f965 commit 211946c

File tree

1 file changed

+44
-9
lines changed

1 file changed

+44
-9
lines changed

src/org/freedesktop/gstreamer/Bus.java

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@
5454
* first-in first-out way from the streaming threads to the application.
5555
* <p>
5656
* See upstream documentation at
57-
* <a href="https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstBus.html"
58-
* >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstBus.html</a>
57+
* <a href="https://gstreamer.freedesktop.org/documentation/gstreamer/gstbus.html"
58+
* >https://gstreamer.freedesktop.org/documentation/gstreamer/gstbus.html</a>
5959
* <p>
6060
* Since the application typically only wants to deal with delivery of these
6161
* messages from one thread, the Bus will marshal the messages between different
@@ -80,10 +80,11 @@ public class Bus extends GstObject {
8080
private static final Logger LOG = Logger.getLogger(Bus.class.getName());
8181
private static final SyncCallback SYNC_CALLBACK = new SyncCallback();
8282

83+
private volatile BusSyncHandler syncHandler = null;
84+
8385
private final Object lock = new Object();
8486
private final List<MessageProxy<?>> messageProxies = new CopyOnWriteArrayList<>();
8587
private boolean watchAdded = false;
86-
private BusSyncHandler syncHandler = null;
8788

8889
/**
8990
* This constructor is used internally by gstreamer-java
@@ -468,14 +469,46 @@ public boolean post(Message message) {
468469
return GSTBUS_API.gst_bus_post(this, message);
469470
}
470471

471-
public BusSyncHandler getSyncHandler() {
472-
return syncHandler;
473-
}
474-
472+
/**
473+
* Sets the synchronous handler (message listener) on the bus. The handler
474+
* will be called every time a new message is posted on the bus. Note that
475+
* the handler will be called in the same thread context as the posting
476+
* object. Applications should generally handle messages asynchronously
477+
* using the other message listeners.
478+
* <p>
479+
* Only one handler may be attached to the bus at any one time. An attached
480+
* sync handler forces creation of {@link Message} objects for all messages
481+
* on the bus, so the handler should be removed if no longer required.
482+
* <p>
483+
* A single native sync handler is used at all times, with synchronous and
484+
* asynchronous dispatch handled on the Java side, so the bindings do not
485+
* inherit issues in clearing or replacing the sync handler with versions of
486+
* GStreamer prior to 1.16.3.
487+
*
488+
* @param handler bus sync handler, or null to remove
489+
*/
475490
public void setSyncHandler(BusSyncHandler handler) {
476491
syncHandler = handler;
477492
}
478493

494+
/**
495+
* Clear the synchronous handler.
496+
* <p>
497+
* This is a convenience method equivalent to {@code setSyncHandler(null)}
498+
*/
499+
public void clearSyncHandler() {
500+
setSyncHandler(null);
501+
}
502+
503+
/**
504+
* Get the current synchronous handler.
505+
*
506+
* @return current sync handler, or null
507+
*/
508+
public BusSyncHandler getSyncHandler() {
509+
return syncHandler;
510+
}
511+
479512
/**
480513
* Connects to a signal.
481514
*
@@ -880,9 +913,11 @@ private static class SyncCallback implements GstBusAPI.BusSyncHandler {
880913
@Override
881914
public BusSyncReply callback(final GstBusPtr busPtr, final GstMessagePtr msgPtr, Pointer userData) {
882915
Bus bus = Natives.objectFor(busPtr, Bus.class, true, true);
883-
if (bus.syncHandler != null) {
916+
// volatile - use local reference
917+
BusSyncHandler syncHandler = bus.syncHandler;
918+
if (syncHandler != null) {
884919
Message msg = Natives.objectFor(msgPtr, Message.class, true, true);
885-
BusSyncReply reply = bus.syncHandler.syncMessage(msg);
920+
BusSyncReply reply = syncHandler.syncMessage(msg);
886921
if (reply != BusSyncReply.DROP) {
887922
Gst.getExecutor().execute(() -> bus.dispatchMessage(busPtr, msgPtr));
888923
} else {

0 commit comments

Comments
 (0)