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 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> <mailto:</pre><a href=3D"mailto:Jack-Devel@li= sts.jackaudio.org"><pre>[email protected]</pre></a><pre>></= 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==--