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

fix suspend in session master when fork_on_start #296

Merged
merged 1 commit into from
Apr 11, 2024

Conversation

smemsh
Copy link
Contributor

@smemsh smemsh commented Apr 10, 2024

After commit b102add following request #287, term->master is used as test to see if this is session master process we want to wakeup with SIGCONT after suspend (master must be kept running, or other slaves will block). Test uses comparison term->fdout == 1, which is never true in the case of forked master when ui.session.fork_on_start. The forked master has different (>10) fdout descriptor numbers, so it will never be term->master and thus master_pid will still have its initialized value 0.

Instead we can get the pid directly after forking, and use the interlink creation attempt to decide whether this is a master or slave process depending on successful connect(). This was tested with both fork_on_start=1 and fork_on_start=0 with different suspend/resume permutations and seems to work correctly now.

Note that term->master is used in several places: exec_on_terminal(), try_to_draw_images(), redraw_screen(), erase_screen(), get_resource_info() and get_master_session(), so it could be that fork_on_start has other issues.

…n_start

When ui.sessions.fork_on_start, we fork a process that has a different
fdout than get_output_handle() (which has hardcoded fdout of 1), so it
will never be considered term->master, yet this is the process we want
to wake up in SIGTSTP handler.

Since we cannot rely on term->master to determine if we are the master
process, we instead move master_pid to be set explicitly at the places
where we have information about whether our process is a master or a
slave: first on start, then once the interlink determination has been
made.

master_pid has to be set in both parent and child, because both will get
suspended and need to know which one needs to resume in background with
SIGCONT (the master).  We can't inherit from the parent because it's
unknown at the time of fork.

Previously, master_pid worked correctly with fork_on_start=0,
-no-connect or -dump, but not with fork_on_start=1.

See rkd77#287 for background.
@smemsh
Copy link
Contributor Author

smemsh commented Apr 10, 2024

Also, what systems don't HAVE_GETPID? I can't imagine elinks working with fork_on_start set now, without getpid()...

@smemsh
Copy link
Contributor Author

smemsh commented Apr 10, 2024

Just to clarify, slaves, and fork_on_start=0 work fine as-is, so my use case was good, which is why I didn't notice. However with fork_on_start=1, suspending the first process will also suspend the forked master, without this patch.

@rkd77 rkd77 merged commit 605f2d8 into rkd77:master Apr 11, 2024
@rkd77
Copy link
Owner

rkd77 commented Apr 11, 2024

Seems to be good. Thanks

@smemsh
Copy link
Contributor Author

smemsh commented Apr 11, 2024

I think it probably doesn't work right without HAVE_GETPID, but I don't know what system I can use to test it? Should we consider removing HAVE_GETPID and just breaking on systems without it?

Does Windows define this? I don't have such a system available to check.

@rkd77
Copy link
Owner

rkd77 commented Apr 11, 2024

DJGPP has getpid() also MINGW has it, so check for getpid() was removed.

@smemsh smemsh deleted the masterpid-forkonstart branch April 13, 2024 10:11
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.

2 participants