Handle SIGUSR1 signal by calling the corresponding vimscript function#1718
Handle SIGUSR1 signal by calling the corresponding vimscript function#1718JacobHayes wants to merge 2 commits intovim:masterfrom
Conversation
|
It would make sense to remove the handler and create a new autocommand instead. Autocomands do not give any error messages when absent, require less code for simple thing like I would also suggest to be consistent and provide both USR1 and USR2 handlers. Also what “known conflicts” you are referring to? Note regarding names: I can suggest one of three: Personally in favour of the last one: it would be easier to determine whether handler needs to be installed if it would later be chosen to support other events (e.g. Also you must not call anything from a signal handler, signal may arrive at any time and disturb other activities, this especially applies for non-deadly signals and this especially applies to your code because you are going to run something highly complicated like processing VimL which has lots of interactions with globals*. You need to act like SIGINT/SIGWINCH/SIGALARM: just set a flag and return. Process flag later in the event loop and wherever else you feel necessary. And you are missing tests. * : E.g. what if your signal arrives while Vim is in the middle of allocating a list, after |
src/os_unix.c
Outdated
| # if defined(FEAT_USR_CMDS) | ||
| typval_T rettv; | ||
| call_vim_function(SIGUSR1_HANDLER_NAME, 0, NULL, FALSE, TRUE, &rettv); | ||
| clear_tv(&rettv); |
There was a problem hiding this comment.
This can't work as-is. You're not allowed to use dynamically allocate/free memory in a signal handle among plenty of other things. Signals are error prone. A signal handler should be re-entrant and merely set a volatile a variable and not much more. That volatile variable can then be checked later when dispatching events outside of the signal handler.
See: https://www.gnu.org/software/libc/manual/html_node/Nonreentrancy.html
|
Jacob Hayes wrote:
This is a stab at allowing users to add custom handlers for the
SIGUSR1 signal. My use case was automatically reloading the
configuration file in all open vim processes. I chose SIGUSR1 as it is
commonly used for custom handlers and, unlike SIGUSR2, doesn't appear
to have any known conflicts.
The PR sets the SIGUSR1 signal as 'non-deadly' and attaches a handler
function that calls the vimscript function `SIGUSR1_handler`.
Aside from general fitness for this in core vim, I'm unsure about a
few implementation details:
- The vimscript handler's name is defined in `os_unix.c` above the C
wrapper function. Does that better fit in a header file?
- Would it make sense to provide a default noop handler or is the
current "Unknown function" message suitable?
I appreciate any feedback!
This seems useful, but needs some tweaks to make it universally useful.
Is there any equivalent on MS-Windows? Would be good to look into that
before settling on the syntax for Vim script.
When there is no SIGUSR1_handler function it should be a no-op, looks
like with your patch it would report an error.
What if there are two plugins that want to handle the signal? It's
probably better to have a function to add a handler and another to
remove it. So that there can be several at the same time.
Or use autocommands, as Nikolai suggested.
…--
SECOND SOLDIER: It could be carried by an African swallow!
FIRST SOLDIER: Oh yes! An African swallow maybe ... but not a European
swallow. that's my point.
"Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD
/// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
|
|
On Tue, May 23, 2017 at 4:57 AM, Bram Moolenaar ***@***.***> wrote:
Jacob Hayes wrote:
> This is a stab at allowing users to add custom handlers for the
> SIGUSR1 signal. My use case was automatically reloading the
> configuration file in all open vim processes. I chose SIGUSR1 as it is
> commonly used for custom handlers and, unlike SIGUSR2, doesn't appear
> to have any known conflicts.
>
> The PR sets the SIGUSR1 signal as 'non-deadly' and attaches a handler
> function that calls the vimscript function `SIGUSR1_handler`.
>
> Aside from general fitness for this in core vim, I'm unsure about a
> few implementation details:
> - The vimscript handler's name is defined in `os_unix.c` above the C
> wrapper function. Does that better fit in a header file?
> - Would it make sense to provide a default noop handler or is the
> current "Unknown function" message suitable?
>
> I appreciate any feedback!
This seems useful, but needs some tweaks to make it universally useful.
Is there any equivalent on MS-Windows? Would be good to look into that
before settling on the syntax for Vim script.
When there is no SIGUSR1_handler function it should be a no-op, looks
like with your patch it would report an error.
https://msdn.microsoft.com/en-us/library/xdkz3x12.aspx
Some signals are supported, but the one in question is not.
What if there are two plugins that want to handle the signal? It's
probably better to have a function to add a handler and another to
remove it. So that there can be several at the same time.
Or use autocommands, as Nikolai suggested.
In C/POSIX the last call to `signal()` sets the handling function. The
equivalent action might be using the last processed function name.
Setting it up so that the signal is an event that commands could
subscribe to is probably the better option, and seems to be what
autocommands do. If the change is added this way, please consider
supporting arbitrary signals.
|
|
Wow, thank you all for the great feedback! Using events to trigger autocmds sounds perfect for this. My plan is to add a @ZyX-I: @ R0b0t1: |
|
On Tue, May 23, 2017 at 3:10 PM, Jacob Hayes ***@***.***> wrote:
@ R0b0t1:
Could you elaborate a bit more on supporting arbitrary signals? With
autocmds, each signal would have to have it's own status variable, event and
signal handler. Otherwise, it would not be possible to have separate
handlers for different signals.
Having the code be extensible. There's no sense in adding signals
(preemptively) that aren't useful to you, but I would hope the pattern
is easy to copy for new additions.
|
I know that I'm answering by someone else, sorry. But one interesting way to do that would be to use the
This is the plan, but the variable could be renamed to The bad side is that if two different signals arrive at almost the same time one of them is lost, i.e. only one signal is caught whilst others are lost. Which should not be something bad, since, by design, if two (or more) of the same signal arrive at the same time (or during a period when they're blocked) only one is delivered. |
|
@grochmal |
Codecov Report
@@ Coverage Diff @@
## master #1718 +/- ##
===========================================
- Coverage 74.94% 2.52% -72.42%
===========================================
Files 76 70 -6
Lines 124906 117838 -7068
===========================================
- Hits 93609 2977 -90632
- Misses 31297 114861 +83564
Continue to review full report at Codecov.
|
|
I've updated it to use an autocmd for SigUSR1, though I'm not sure how to proceed with the test. I believe the signal is sent, however because it is not processed until after the function is run, the test fails. Any thoughts on that or a better way to test? Another downfall with the current implementation is a command has to be entered before the autocmd(s) will be called. In my case, I'm changing the theme and would like it to change without having to go to each session to do something. I was hoping to add extra @ZyX-I I like the array idea (as opposed to a shared simple value). I'm thinking an array of structs that contain the |
|
it's probably better to use a bitset here: it's more flexible (and efficient for all it matters) and it'd make supporting cases like |
|
@LemonBoy Not bitset, never for signals. Unless there is an atomic command “set bit X to 1 at location 0x…” this is going to be “load register, 0x…; or register, mask; store 0x…, register;” and it is completely possible to receive signal after loading, but before storing which is not a problem for integer arrays (there just is one store). The assembler of And I do not think that |
|
Dealing with the signal only in main_loop() means nothing will happen when in Insert mode. |
eb6e89e to
8d06502
Compare
Codecov Report
@@ Coverage Diff @@
## master #1718 +/- ##
==========================================
+ Coverage 81.83% 81.83% +<.01%
==========================================
Files 133 133
Lines 146551 146559 +8
==========================================
+ Hits 119933 119940 +7
- Misses 26618 26619 +1
Continue to review full report at Codecov.
|
|
@brammool thanks for the Working in insert mode is definitely an improvement. One keypress is required for the autocmd to be called. For a color change, a second keypress is required to update the color, but if I force a |
|
@brammool thanks for the `parse_queued_messages` tip. I rebased this
work on top of master and moved the autocmd calling logic there and
fixed the test.
Working in insert mode is definitely an improvement. One keypress is
required for the autocmd to be called. For a color change, a second
keypress is required to update the color, but if I force a `redraw` in
the autocmd, I can avoid the second keypress. Here's the `.vimrc` I
was testing with:
```
echo("sourcing vimrc")
au SigUSR1 * source $MYVIMRC | redraw
highlight Normal ctermfg=grey ctermbg=black
```
Thanks. So now it should work. Can you please add documentation? With
some hints about how to check if the mechanism is supported. And what
happens to a Vim version that does not support handling the signal.
…--
ARTHUR: Ni!
BEDEVERE: Nu!
ARTHUR: No. Ni! More like this. "Ni"!
BEDEVERE: Ni, ni, ni!
"Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD
/// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
|
Problem: No simple way to interrupt Vim.
Solution: Add the SigUSR1 autocommand, triggered by SIGUSR1. (Jacob Hayes,
closes vim/vim#1718)
vim/vim@be5ee86
Problem: No simple way to interrupt Vim.
Solution: Add the SigUSR1 autocommand, triggered by SIGUSR1. (Jacob Hayes,
closes vim/vim#1718)
vim/vim@be5ee86
This is a stab at allowing users to add custom handlers for the SIGUSR1 signal. My use case was automatically reloading the configuration file in all open vim processes. I chose SIGUSR1 as it is commonly used for custom handlers and, unlike SIGUSR2, doesn't appear to have any known conflicts.
The PR sets the SIGUSR1 signal as 'non-deadly' and attaches a handler function that calls the vimscript function
SIGUSR1_handler.Aside from general fitness for this in core vim, I'm unsure about a few implementation details:
os_unix.cabove the C wrapper function. Does that better fit in a header file?I appreciate any feedback!