Fun with Forking

2 views
Skip to first unread message

Nico Weber

unread,
Feb 14, 2008, 6:10:09 PM2/14/08
to vim...@googlegroups.com
Hi all,

I took a look at the forking code. Vim's startup basically works like
this:

main()
....
parse --remote* arguments (this calls code in MMBackend already)
...
read .vimrc
...
(init parts of gui)
start gui (here we usually call fork(), shutdown(), exec() and
start a new vim instance that goes through all the steps again one
more time)


There are several problems with this approach:
1. If the shutdown code between fork() and exec() calls Core
Foundation code, OS X dies.
2. Some work is done twice
3. If MacVim is not yet running and you do `mvim --remote`, you get
the warning that no server was found and one will be started twice
(once during --remote parsing before the fork, once after that).

As a remedy, I thought about pulling the forking logic right at the
start of main (basically `if we're going to fork, do it right now').
This fixes the problems listed above, but has its own set of problems.
1. Currently, the checks if vim should fork are distributed over
several places. Pulling all this at the start of main() duplicates
code and is not completely trivial to get right ("if the gui should be
started, we want to fork. Except when -f if passed to. vim -gf means
gui and no fork, but vim -fg means something else. vim -g --remote -f
does fork because the -f is protected by the --remote. …"). Worse, if
the vim forking logic should ever change, we have to change the
duplicated code as well (the Right Thing is to put the forking logic
into its own function and use that in core vim as well, but it's
unlikely that a patch of this kind would be accepted in core vim, so
it's not really a solution).
2. It's possible to add 'f' to your 'guioptions' in your .vimrc (which
means "don't fork in gui mode"). There's no way to know that right at
the start of main, so we couldn't honor this setting.

I thought a bit about this, and I believe the best solution is to keep
the forking logic where it is, but to move the shutdown() code from
between fork() and exec() above the exec. This way, no code is
executed between fork() and exec() and there's no way to introduce a
"Honey, I called Core Foundation after fork()" problem anymore. We
still have the somewhat surprising behavior that --remote commands are
executed twice _if MacVim is not yet running_, but I believe that's
the lesser of two evils. With the attached patch, the `if(gui.dofork)`
line introduced in the emergency patch can be removed again.

Nico

fork2.patch

björn

unread,
Feb 16, 2008, 12:37:30 PM2/16/08
to vim...@googlegroups.com

I agree with your conclusion and have merged your patch. Passing
--remote when MacVim isn't running is not something you should do
anyway, so I think it is fine.

Thanks for the patch,
Björn

Reply all
Reply to author
Forward
0 new messages