gstreamer-java / gst1-java-core

Java bindings for GStreamer 1.x
GNU Lesser General Public License v3.0
194 stars 72 forks source link

avoid deadlock by synchronizing on addEventProbe #196

Closed MaZderMind closed 4 years ago

MaZderMind commented 4 years ago

So based on this simple Gist I was able to trace a Deadlock within the block-Call, where the Main and one of the GstBus-Threads seem to deadlock upon calling synchronized methods within Pad and Pad.Handle. I'm not yet sure how the respective calling paths are and which action results in the deadlock, but it is very quickly (wihin a couple of seconds) reproducible with the 1.1.0 release.

[main] INFO Main - > blocking
[main] INFO Main - < getting
[GstBus] INFO Main - = blocked
[GstBus] INFO Main - = completed
[main] INFO Main - < got
[main] INFO Main - > blocking
[main] INFO Main - = blocked
[main] INFO Main - = completed

Thread Info:

"main@1" prio=5 tid=0x1 nid=NA waiting for monitor entry
  java.lang.Thread.State: BLOCKED
     blocks GstBus@1407
     waiting for GstBus@1407 to release lock on <0x5b9> (a org.freedesktop.gstreamer.Pad)
      at org.freedesktop.gstreamer.glib.GObject.removeCallback(GObject.java:412)
      at org.freedesktop.gstreamer.Pad.access$100(Pad.java:87)
      at org.freedesktop.gstreamer.Pad$1.eventReceived(Pad.java:330)
      at org.freedesktop.gstreamer.Pad$4.callback(Pad.java:447)
      at sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source:-1)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:498)
      at com.sun.jna.CallbackReference$DefaultCallbackProxy.invokeCallback(CallbackReference.java:520)
      at com.sun.jna.CallbackReference$DefaultCallbackProxy.callback(CallbackReference.java:551)
      at com.sun.jna.Native.invokeLong(Native.java:-1)
      at com.sun.jna.Function.invoke(Function.java:428)
      at com.sun.jna.Function.invoke(Function.java:361)
      at com.sun.jna.Library$Handler.invoke(Library.java:265)
      at com.sun.proxy.$Proxy13.gst_pad_add_probe(Unknown Source:-1)
      at org.freedesktop.gstreamer.Pad$Handle.addProbe(Pad.java:735)
      - locked <0x5bb> (a org.freedesktop.gstreamer.Pad$Handle)
      at org.freedesktop.gstreamer.Pad$Handle.access$200(Pad.java:715)
      at org.freedesktop.gstreamer.Pad.addEventProbe(Pad.java:455)
      at org.freedesktop.gstreamer.Pad.block(Pad.java:327)
      at Main.main(Main.java:31)
"GstBus@1407" daemon prio=5 tid=0x12 nid=NA waiting for monitor entry
  java.lang.Thread.State: BLOCKED
     blocks main@1
     waiting for main@1 to release lock on <0x5bb> (a org.freedesktop.gstreamer.Pad$Handle)
      at org.freedesktop.gstreamer.Pad$Handle.removeProbe(Pad.java:744)
      at org.freedesktop.gstreamer.Pad$Handle.access$400(Pad.java:715)
      at org.freedesktop.gstreamer.Pad$5.disconnect(Pad.java:465)
      at org.freedesktop.gstreamer.glib.GObject$GCallback.remove(GObject.java:596)
      at org.freedesktop.gstreamer.glib.GObject.removeCallback(GObject.java:417)
      - locked <0x5b9> (a org.freedesktop.gstreamer.Pad)
      at org.freedesktop.gstreamer.Pad.access$100(Pad.java:87)
      at org.freedesktop.gstreamer.Pad$1.eventReceived(Pad.java:330)
      at org.freedesktop.gstreamer.Pad$4.callback(Pad.java:447)
      at sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source:-1)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:498)
      at com.sun.jna.CallbackReference$DefaultCallbackProxy.invokeCallback(CallbackReference.java:520)
      at com.sun.jna.CallbackReference$DefaultCallbackProxy.callback(CallbackReference.java:551)

This can be mitigated ba synchronizing on addEventProbe, as it is already done in addDataProbe

This fix is part of a set of fixes for #184 and is extracted from #186