Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement openURL on Linux #642

Merged
merged 1 commit into from
Feb 21, 2019

Conversation

baconpaul
Copy link
Collaborator

Implement openURL using xdg-open, the freedesktop.org command to
open a resource in the default browser or viewer.

Closes #638 menu manual on linux broken

@baconpaul
Copy link
Collaborator Author

baconpaul commented Feb 21, 2019

Heya @falkTX and @jsakkine just want to make sure you agree with my choice of "xdg-open" here as best bet to open a URL on Linux. Thanks!

@falkTX
Copy link
Contributor

falkTX commented Feb 21, 2019

xdg-open is the right tool to use, but I am not sure if system is a good thing in the context of a plugin.
the manual tells us it uses fork which is quite nasty in plugins.
vfork with exec should be the way to go if we can

@baconpaul
Copy link
Collaborator Author

Great - this is why I ask!

Thanks

@baconpaul baconpaul force-pushed the linux-browser-638 branch 2 times, most recently from 0f1547f to fdc530b Compare February 21, 2019 19:04
@baconpaul
Copy link
Collaborator Author

@falkTX this works no problem and is indeed better! Looks right to me too. Can you give a quick peek?

Thanks!

@@ -31,6 +33,13 @@ namespace Surge

void openURL(const std::string &url)
{
if (vfork()==0)
{
if (execlp("xdg-open", "xdg-open", url.c_str(), (char*)NULL) < 0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

last argument can be nullptr
I would just test this in a system without xdg-open or purposefully renaming things here in order to make it call something that does not exist, and see how that behaves.
if that works, then we should be fine.

@baconpaul
Copy link
Collaborator Author

30+ years of typing NULL is gonna be a hard habit to break. I’ll fix before I sweep.

I accidentalky tested what you said in my first version where I had a typo in xdg home. Nothing bad happened but of course the url didn’t open. I considered saying something to stderr but decided against it. I think thats ok - not sure what happens to stderr from a child process in hosts and also seems it would force a copy of some system resource into the child which is why you suggested vfork

Thanks again for the reviews!!

@baconpaul
Copy link
Collaborator Author

I gotta say, reading the vfork man page more carefully it really seems like a worse choice than fork I agree @jsakkine - but I've never written linux audio code.

@falkTX why the vfork vs fork?

@falkTX
Copy link
Contributor

falkTX commented Feb 21, 2019

vfork is the function to use when we deal with audio plugins and realtime stuff.
the ardour devs explain it in some details here https://github.com/Ardour/ardour/tree/master/libs/vfork

@falkTX
Copy link
Contributor

falkTX commented Feb 21, 2019

We can ignore the part about file descriptors, as we do not care about them here.

@baconpaul
Copy link
Collaborator Author

Right; so "make a copy on write version of the entire process space" vs "block until I hit exec one instruction later" is the tradeoff and ardour picked the second. Part of me thinks @jsakkine may explain how much better the linux copy on write at fork time is now than 5 years ago when the ardour team wrote that (and he's probably correct).

So I dunno.

Plus it doesn't really matter in this instance; this is when a user does menu / open manual and it starts firefox or what not. Not a performance-moment event.

So I'm tempted to follow what ardour does and use vfork just so our linux users can read the manual! Or follow more standard code and use fork just so our linux users can read the manual!

@jsakkine your thoughts?

@jarkkojs
Copy link
Collaborator

On modern systems the performance difference is very modest but yes in some cases it probably makes sense as @falkTX stated (or alternatively using raw clone() with CLONE_VFORK flag) and in 99% of cases it does not. Nice thing in constrained memory systems when using vfork() is that it does not temporarily commit memory for a new process. Actually, if you don't have MMU in your CPU you have to use vforkO.

I wasn't saying that please don't use it. I was just wondering was there any particular reason for opening on URL :) I'd guess that either would be seamless to use here...

@baconpaul
Copy link
Collaborator Author

Ok cool! Like I said I learned just today that there was a second fork! (Learn something new every day). So wasn’t sure if your question was a “no don’t do this” version of why or so “why” version of why!

I’ll change null to nullptrr and merge

Thanks for the looks here. Really appreciate us being careful with this software

Implement openURL using xdg-open, the freedesktop.org command to
open a resource in the default browser or viewer.

Closes surge-synthesizer#638 menu manual on linux broken

Incorporate @falkTX comments to use vfork rather than system
@baconpaul baconpaul merged commit 5c5ac54 into surge-synthesizer:master Feb 21, 2019
@jarkkojs
Copy link
Collaborator

jarkkojs commented Feb 21, 2019

You should stick to fork() unless you block all the signals before calling vfork() because otherwise the signal handlers might be executed in the context of the child process. We need to fix this by blocking the signals.

Also if the parent process has any threads using vfork() can be nasty because they continue to execute in the child context. Fixing this issue requires a full audit on how Surge uses threads and make appropriate quirks around the codebase.

Sorry, was a long time since I've given a thought to vfork(). Took time to recall its dark sides but yes for these reasons you should not use it unless you have a hard reason to use it. If you have a really good reason, go for it, but it should be this way around, not as the default choice for everything.

@jarkkojs
Copy link
Collaborator

Looked at GLIBC source code. Looks like unless I got it wrong somehow that GLIBC always fallbacks to regular fork() when you call vfork(). I don't question this much because it doesn't really play well with multi-threading.

Still for correctness sake this should be fixed by replacing vfork() with fork().

@baconpaul
Copy link
Collaborator Author

OK! I'll probably be back in there soon anyway doing the open my patches area; I will fix it then.

thanks!

@falkTX
Copy link
Contributor

falkTX commented Feb 22, 2019

I do not get why we are backtracking now, I thought the reasons for using vfork were pretty clear...
In fact, in Carla, I disable the use of fork by plugins, as it is known to not be so nice for realtime audio applications.

@baconpaul
Copy link
Collaborator Author

Ok I'll leave it then. It's only one menu item after all!

@baconpaul baconpaul deleted the linux-browser-638 branch February 24, 2019 12:48
@jarkkojs
Copy link
Collaborator

@baconpaul, It really should be fixed.
@falkTX, please read my comments. If you have better knowledge, please share it.

baconpaul added a commit to baconpaul/surge that referenced this pull request Jul 10, 2019
Implement openURL using xdg-open, the freedesktop.org command to
open a resource in the default browser or viewer.

Closes surge-synthesizer#638 menu manual on linux broken

Incorporate @falkTX comments to use vfork rather than system

Former-commit-id: a20270b229645745950f006946d1741f2aa8e884 [formerly 5c5ac54]
Former-commit-id: 04736b8a465b80425cfcca5d2b1ab6f94a8ceb69
Former-commit-id: 08662f5d55de796b010939fe96896468c2b63f24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants