Re: Cannot callback the server in notification thread!

Ethan Funk <[email protected]> Sat, 10 Aug 2019 15:42:15 -0700
Newsgroups gmane.comp.audio.jackit
Organization Red Mountain Radio LLC
Message-ID <b8e0f72c229557102e0867162aa54b522a3ebe3f.camel@redmountainradio.com>
--===============8040715183263885111==
Content-Type: multipart/signed; micalg="pgp-sha512";
	protocol="application/pgp-signature"; boundary="=-ibs0YSSY/3N+26qqdovF"


--=-ibs0YSSY/3N+26qqdovF
Content-Type: multipart/alternative; boundary="=-hkHWB8cERgecHCfJ06eQ"


--=-hkHWB8cERgecHCfJ06eQ
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

I am only writing for Jack2:  I absolutely need to be able to "plug and
unplug" jack clients while audio is running.  However, I decided to use
spin-locks to make sure my jack_port_id queue is write concurrent
safe.  That seemed like a good compromise, considering how little time
the locks are held, and that the hold time is deterministic.
I am porting a radio automation system I originally wrote of OS X/Core
Audio.  I made design decision to make all the media players and
recorders/encoders there own processes that connect to the mixer-core
via jack. So jack connections are being made to the mixer and then
removed periodically, and that needs to happen without audio drop-
out.  So far, working well.
The recorder/encoder process, which I am working on right now, needs to
be optionally able to reconnect to the mixer, or a processing chain
connected to the mixer if it goes away and is restarted.  That is what
this was all about.
I will likely give the core mixer/control program similar persistent
functionality next.
Thanks,Ethan...


On Fri, 2019-08-09 at 14:50 -0400, Tim wrote:
> On 8/9/19 12:01 PM, Ethan Funk wrote:
> > Yes, what you describe is what I am implementing. I have also
> > called it "persistence" in my application. Normally, when all audio
> > ports are disconnected, my application quits. But I have an command
> > line option to keep it running and have it "persist," not quit, try
> > to reconnect.
>=20
> I took it one step further and the 'persistence' is stored in
> the  song file so that the next time the song is loaded, MusE does
> not  complain that this or that is missing and will be removed,
> instead  it simply chugs along happily and when the device
> reappears,  everything works as before.
> I have slowly adopted a policy of "nothing is removed from a
> song  behind the user's back unless they specifically say so, even if
> it  is ultimately missing some component, such as a port is
> missing  or a plugin is missing on the system".Thus, persistent...
> everything! across sessions is the goal.
> > I just implemented a simple queue of jack_port_ids. Callbacks add
> > their relevant port_ids into the queue, with my main thread
> > checking the queue periodically, to further check the queued ports
> > for re-connection. This was not as hard as I though it would be,
> > and works well so far. Just queueing the port id is a lot simpler
> > that what you are doing in MusE, but it is sufficient for my
> > application.
>=20
> Yes, as you might see, I actually store a few callback types in
> our  callback queue and I must 'review' the queue when something
> happens  to carefully determine what exactly took place, for
> example  did a port disconnection happen before an unregistration
> or  was it an unregistration alone, etc.It was tricky. Those port ID
> functions sure help though.
> > One remaining question: Am I safe assuming that jack2 will call my
> > callbacks one at a time from a single thread, or do I need to make
> > my port id queue writing function thread safe, just in case jack2
> > calls my callbacks concurrently?
>=20
> Don't quote me, I might be getting this wrong, if I recall correctly
> ;-)Jack 1 issues all callbacks in the realtime audio thread.Jack 2
> issues some important callbacks, such as the Sync callback,  in the
> realtime audio thread, but most other callbacks are  issued in ONE
> separate thread.Therefore I don't think it could call them
> concurrently,  but I'm not an expert here...I think our queue is
> multi-writer anyway so I probably might not  have noticed if they
> were concurrent, but I don't think I  noticed anything unusual.
> Tim.
> > Ethan...
> > On Fri, 2019-08-09 at 01:52 -0400, Tim wrote:
> > > On 8/8/19 10:20 PM, Ethan Funk wrote:
> > > > In an application I am writing, I am getting an error message
> > > > out stderr(see email subject), and a connection failure return
> > > > result, when I tryto use jack_connect() from inside a
> > > > jack_set_port_registration_callbackfunction, using Jack2. My
> > > > goal is to have the application remember andre-connect to a
> > > > disconnected port if/when it "comes back." Am I going toneed to
> > > > create a mostly sleeping thread just for port re-
> > > > connectionsattempts, or is there something obvious I am
> > > > missing?
> > > > Thanks,Ethan...
> > >=20
> > > If I understand your goal, I did this in MusE.I called it
> > > 'persistent connections', or 'persistent ports'.
> > > For example you can unplug a USB midi device currently   in use
> > > by MusE as a 'Jack device', then re-plug it,   and MusE will
> > > automatically reconnect to its ports   as if nothing happened and
> > > you may continue playing.(I made our 'ALSA devices' do the same
> > > thing!)It should also work with other Jack clients.
> > > Look in our driver/jack.cpp, at:    static void
> > > registration_callback(...),    static void
> > > port_connect_callback(...),   and    static int
> > > graph_callback(...),    // This is called in the gui
> > > context,    //  triggered by graph_callback()    void
> > > JackAudioDevice::graphChanged().
> > > It was complicated. Very. I needed to support Jack 1 and 2.So
> > > there are a few sequences of calls and resulting   sequences of
> > > callbacks for example that are different   in Jack 1 and 2.
> > > Several tricks and traps. See comments.
> > > My system relies HEAVILY on the jack port 'alias
> > > names',   because it was pretty much the ONLY thing you can rely
> > > on,   because the regular port names and port numbers
> > > change   upon re-plugging. It automatically chooses which alias
> > > is   best or falls back to the not so good canonical port name.
> > > So, that's what it 'remembers' between device plug ins -   simply
> > > the port alias or name text.
> > > HTH.Tim._______________________________________________Jack-Devel=20
> > > mailing [email protected]
> > >  <mailto:[email protected]>
> > > http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org
> > >=20

--=-hkHWB8cERgecHCfJ06eQ
Content-Type: text/html; charset="utf-8"
Content-Transfer-Encoding: quoted-printable

<html dir=3D"ltr"><head></head><body style=3D"text-align:left; direction:lt=
r;"><div>I am only writing for Jack2:  I absolutely need to be able to "plu=
g and unplug" jack clients while audio is running.  </div><div>However, I d=
ecided to use spin-locks to make sure my jack_port_id queue is write concur=
rent safe.  That seemed like a good&nbsp;compromise, considering how little=
 time the locks are held, and that the hold time is deterministic.</div><di=
v><br></div><div>I am porting a radio automation system I originally wrote =
of OS X/Core Audio.  I made design decision to make all the media players a=
nd recorders/encoders there own processes that connect to the mixer-core vi=
a jack. So jack connections are being made to the mixer and then removed pe=
riodically, and that needs to happen without audio drop-out.  So far, worki=
ng well.</div><div><br></div><div>The recorder/encoder process, which I am =
working on right now, needs to be optionally able to reconnect to the mixer=
, or a processing chain connected to the mixer if it goes away and is resta=
rted.  That is what this was all about.</div><div><br></div><div>I will lik=
ely give the core mixer/control program similar persistent functionality ne=
xt.</div><div><br></div><div>Thanks,</div><div>Ethan...</div><div><br></div=
><div><br></div><div><br></div><div>On Fri, 2019-08-09 at 14:50 -0400, Tim =
wrote:</div><blockquote type=3D"cite" style=3D"margin:0 0 0 .8ex; border-le=
ft:2px #729fcf solid;padding-left:1ex"><pre>On 8/9/19 12:01 PM, Ethan Funk =
wrote:</pre><blockquote type=3D"cite" style=3D"margin:0 0 0 .8ex; border-le=
ft:2px #729fcf solid;padding-left:1ex"><pre>Yes, what you describe is what =
I am implementing. I have also called it </pre><pre>"persistence" in my app=
lication. Normally, when all audio ports are </pre><pre>disconnected, my ap=
plication quits. But I have an command line option to </pre><pre>keep it ru=
nning and have it "persist," not quit, try to reconnect.</pre></blockquote>=
<pre><br></pre><pre>I took it one step further and the 'persistence' is sto=
red in the</pre><pre>  song file so that the next time the song is loaded, =
MusE does not</pre><pre>  complain that this or that is missing and will be=
 removed, instead</pre><pre>  it simply chugs along happily and when the de=
vice reappears,</pre><pre>  everything works as before.</pre><pre><br></pre=
><pre>I have slowly adopted a policy of "nothing is removed from a song</pr=
e><pre>  behind the user's back unless they specifically say so, even if it=
</pre><pre>  is ultimately missing some component, such as a port is missin=
g</pre><pre>  or a plugin is missing on the system".</pre><pre>Thus, persis=
tent... everything! across sessions is the goal.</pre><pre><br></pre><block=
quote type=3D"cite" style=3D"margin:0 0 0 .8ex; border-left:2px #729fcf sol=
id;padding-left:1ex"><pre>I just implemented a simple queue of jack_port_id=
s. Callbacks add their </pre><pre>relevant port_ids into the queue, with my=
 main thread checking the queue </pre><pre>periodically, to further check t=
he queued ports for re-connection. This </pre><pre>was not as hard as I tho=
ugh it would be, and works well so far. Just </pre><pre>queueing the port i=
d is a lot simpler that what you are doing in MusE, </pre><pre>but it is su=
fficient for my application.</pre></blockquote><pre><br></pre><pre>Yes, as =
you might see, I actually store a few callback types in our</pre><pre>  cal=
lback queue and I must 'review' the queue when something happens</pre><pre>=
  to carefully determine what exactly took place, for example</pre><pre>  d=
id a port disconnection happen before an unregistration or</pre><pre>  was =
it an unregistration alone, etc.</pre><pre>It was tricky. Those port ID fun=
ctions sure help though.</pre><pre><br></pre><blockquote type=3D"cite" styl=
e=3D"margin:0 0 0 .8ex; border-left:2px #729fcf solid;padding-left:1ex"><pr=
e>One remaining question: Am I safe assuming that jack2 will call my </pre>=
<pre>callbacks one at a time from a single thread, or do I need to make my =
</pre><pre>port id queue writing function thread safe, just in case jack2 c=
alls my </pre><pre>callbacks concurrently?</pre></blockquote><pre><br></pre=
><pre>Don't quote me, I might be getting this wrong, if I recall correctly =
;-)</pre><pre>Jack 1 issues all callbacks in the realtime audio thread.</pr=
e><pre>Jack 2 issues some important callbacks, such as the Sync callback,</=
pre><pre>  in the realtime audio thread, but most other callbacks are</pre>=
<pre>  issued in ONE separate thread.</pre><pre>Therefore I don't think it =
could call them concurrently,</pre><pre>  but I'm not an expert here...</pr=
e><pre>I think our queue is multi-writer anyway so I probably might not</pr=
e><pre>  have noticed if they were concurrent, but I don't think I</pre><pr=
e>  noticed anything unusual.</pre><pre><br></pre><pre>Tim.</pre><pre><br><=
/pre><blockquote type=3D"cite" style=3D"margin:0 0 0 .8ex; border-left:2px =
#729fcf solid;padding-left:1ex"><pre><br></pre><pre>Ethan...</pre><pre><br>=
</pre><pre>On Fri, 2019-08-09 at 01:52 -0400, Tim wrote:</pre><blockquote t=
ype=3D"cite" style=3D"margin:0 0 0 .8ex; border-left:2px #729fcf solid;padd=
ing-left:1ex"><pre>On 8/8/19 10:20 PM, Ethan Funk wrote:</pre><blockquote t=
ype=3D"cite" style=3D"margin:0 0 0 .8ex; border-left:2px #729fcf solid;padd=
ing-left:1ex"><pre>In an application I am writing, I am getting an error me=
ssage out stderr</pre><pre>(see email subject), and a connection failure re=
turn result, when I try</pre><pre>to use jack_connect() from inside a jack_=
set_port_registration_callback</pre><pre>function, using Jack2. My goal is =
to have the application remember and</pre><pre>re-connect to a disconnected=
 port if/when it "comes back." Am I going to</pre><pre>need to create a mos=
tly sleeping thread just for port re-connections</pre><pre>attempts, or is =
there something obvious I am missing?</pre><pre><br></pre><pre>Thanks,</pre=
><pre>Ethan...</pre></blockquote><pre><br></pre><pre>If I understand your g=
oal, I did this in MusE.</pre><pre>I called it 'persistent connections', or=
 'persistent ports'.</pre><pre><br></pre><pre>For example you can unplug a =
USB midi device currently</pre><pre>   in use by MusE as a 'Jack device', t=
hen re-plug it,</pre><pre>   and MusE will automatically reconnect to its p=
orts</pre><pre>   as if nothing happened and you may continue playing.</pre=
><pre>(I made our 'ALSA devices' do the same thing!)</pre><pre>It should al=
so work with other Jack clients.</pre><pre><br></pre><pre>Look in our drive=
r/jack.cpp, at:</pre><pre>    static void registration_callback(...),</pre>=
<pre>    static void port_connect_callback(...),</pre><pre>   and</pre><pre=
>    static int graph_callback(...),</pre><pre>    // This is called in the=
 gui context,</pre><pre>    //  triggered by graph_callback()</pre><pre>   =
 void JackAudioDevice::graphChanged().</pre><pre><br></pre><pre>It was comp=
licated. Very. I needed to support Jack 1 and 2.</pre><pre>So there are a f=
ew sequences of calls and resulting</pre><pre>   sequences of callbacks for=
 example that are different</pre><pre>   in Jack 1 and 2. Several tricks an=
d traps. See comments.</pre><pre><br></pre><pre>My system relies HEAVILY on=
 the jack port 'alias names',</pre><pre>   because it was pretty much the O=
NLY thing you can rely on,</pre><pre>   because the regular port names and =
port numbers change</pre><pre>   upon re-plugging. It automatically chooses=
 which alias is</pre><pre>   best or falls back to the not so good canonica=
l port name.</pre><pre><br></pre><pre>So, that's what it 'remembers' betwee=
n device plug ins -</pre><pre>   simply the port alias or name text.</pre><=
pre><br></pre><pre>HTH.</pre><pre>Tim.</pre><pre>__________________________=
_____________________</pre><pre>Jack-Devel mailing list</pre><a href=3D"mai=
lto:[email protected]"><pre>[email protected]</pr=
e></a><pre><br></pre><pre> &lt;mailto:</pre><a href=3D"mailto:Jack-Devel@li=
sts.jackaudio.org"><pre>[email protected]</pre></a><pre>&gt;</=
pre><pre><br></pre><a href=3D"http://lists.jackaudio.org/listinfo.cgi/jack-=
devel-jackaudio.org"><pre>http://lists.jackaudio.org/listinfo.cgi/jack-deve=
l-jackaudio.org</pre></a><pre><br></pre><pre><br></pre></blockquote></block=
quote></blockquote></body></html>

--=-hkHWB8cERgecHCfJ06eQ--

--=-ibs0YSSY/3N+26qqdovF
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part
Content-Transfer-Encoding: 7bit

-----BEGIN PGP SIGNATURE-----

iQIzBAABCgAdFiEEqU7GtX8ebNmJMAKgrX6X36Kjo04FAl1PSEcACgkQrX6X36Kj
o05X7BAAmwrmZo5I6Bp7Uk5i20ofly0tSEYNoqe1T7IxhHjGjxDWYevbr/3WrbJ7
8DHzSGUSdnrctZp1IfoaxMRmD44PISJ76HuqYU6D8gLs8zCm/ep2qhdssXunlY+f
ISMUdI3NHQo5TTSJRKd/YyJzzh1MmcCOLTdavMTnTCCnvbIaZWHROoPmd7vE6jO7
XluuJsd2IbZnHSbPUKrPoruZXTnQAGPWRzdGVG9pYqEOKqq8WVC5c8xk1SBcYUbE
1pU2v0ijRqNDT6BRO2KCsoA7uDz6gbl+vSUoEB7RfksITZRAFpx34/uW6HUjbM9s
HpTQueHi8EH52u3Q13Dp3CU2nTmL65RSTsefrN15oTa4CIqM37cw3I+Y2+I7137w
gEwb+3iGnzNJ/yogaxEfXa6U+isf7BFK6UqvFQ7b+AO4qMv6n8gcu+VR6vA8ewH8
7B6vlD0j8Id7hxGTzZuK+5s3gQ3ygIdf5w5IJM0fsdqDMPieew8rRxNJs1X6hf7k
YgwnEioQCMzKRnx3hG1R3LDw0JL9hdj8GJ+f0bwGBSYL4kHmfaJ/BGeYwq3UYN5q
JC7GhcawUpvbDEH0K8CWlZC35egTdtwu0iEIqM3/FTDnLuuhusrQyNqs+5wL3/cR
pAa7sEIRVTj74RuLcp1V32vrMwwgY2SVIgnlvTIEhrNYL8Yj7Wo=
=PKkw
-----END PGP SIGNATURE-----

--=-ibs0YSSY/3N+26qqdovF--


--===============8040715183263885111==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
Jack-Devel mailing list
[email protected]
http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org

--===============8040715183263885111==--