Mailing list for all users of the OCaml language and system.
 help / color / mirror / Atom feed
From: Joerg Czeranski <jc@joerch.org>
To: caml-list@inria.fr
Subject: yet another signal mask patch and: what's the indended semantics?
Date: Wed, 19 May 1999 19:44:57 +0200 (MET DST)	[thread overview]
Message-ID: <5vbInDAh9$2ip$1@joerch.org> (raw)

Hi.

These patches are again incremental.  I think most of the signal
stuff is now working.  Stream output isn't reentrant and thus must
not be used in handlers.

Generally, what's the meaning of enter_blocking_section()/
leave_blocking_section()?  Were they intended to be only used in
reentrant C functions?

And what's the semantics of the Unix.xxx functions supposed to be?
While the Single Unix C write() function never blocks are a successful
select(), Unix.write will block until all data is written unless the
descriptor is set to non-blocking mode.

So far I assumed that the semantics should be the same for C and Caml-Unix
functions with the same name.  I didn't yet try to check which functions
are merely wrappers and which implement a higher level semantics.

These questions make me hesitate to use O'Caml "in anger" for low level
Unix programming.

BTW, there are also a few prototypes missing, e.g. the
"extern char ** cstringvect();" in
otherlibs/unix/{execv.c,execve.c,execvp.c} should be
"extern char ** cstringvect(value);" - Ansi doesn't allow mixing
of prototypes and non-prototypes for the same function.

joerch

===== begin patches =====
*** asmrun/signals.c.old	Tue May 18 23:11:51 1999
--- asmrun/signals.c	Tue May 18 23:20:18 1999
***************
*** 13,18 ****
--- 13,19 ----
  
  #include <signal.h>
  #include <stdio.h>
+ #include <string.h> /* for memcpy */
  #if defined(TARGET_power) && defined(__linux)
  #include <asm/sigcontext.h>
  #endif
***************
*** 76,81 ****
--- 77,83 ----
  static void execute_signal(int signal_number, int in_handler)
  {
    struct caml_sigblock_node sigblock_node;
+   sigset_t saved_mask;
    int i;
  
    Assert (!async_signal_mode);
***************
*** 94,105 ****
    sigblock_node.signal_number = signal_number;
    caml_sigblock_stack = &sigblock_node;
  
    sigaddset(&current_signal_mask, signal_number);
    sigprocmask(SIG_SETMASK, &current_signal_mask, NULL);
  
    callback(Field(signal_handlers, signal_number), Val_int(signal_number));
  
!   sigdelset(&current_signal_mask, signal_number);
    /* don't reset the signal mask if we're in the handler, so the handler
       doesn't nest unnecessarily */
    if (!in_handler)
--- 96,108 ----
    sigblock_node.signal_number = signal_number;
    caml_sigblock_stack = &sigblock_node;
  
+   get_current_signal_mask(&saved_mask);
    sigaddset(&current_signal_mask, signal_number);
    sigprocmask(SIG_SETMASK, &current_signal_mask, NULL);
  
    callback(Field(signal_handlers, signal_number), Val_int(signal_number));
  
!   update_signal_mask(&saved_mask);
    /* don't reset the signal mask if we're in the handler, so the handler
       doesn't nest unnecessarily */
    if (!in_handler)
***************
*** 178,194 ****
    if (async_signal_mode) {
      /* We are interrupting a C function blocked on I/O.
         Callback the Caml code immediately. */
-     struct caml_sigblock_node sigblock_node;
- 
-     sigblock_node.next = caml_sigblock_stack;
-     sigblock_node.signal_number = sig;
-     caml_sigblock_stack = &sigblock_node;
- 
      leave_blocking_section();
!     callback(Field(signal_handlers, sig), Val_int(sig));
      enter_blocking_section();
- 
-     caml_sigblock_stack = sigblock_node.next;
    } else {
      /* We can't execute the signal code immediately.
         Instead, we remember the signal and play with the allocation limit
--- 181,189 ----
    if (async_signal_mode) {
      /* We are interrupting a C function blocked on I/O.
         Callback the Caml code immediately. */
      leave_blocking_section();
!     execute_signal(sig, 1 /* in handler */);
      enter_blocking_section();
    } else {
      /* We can't execute the signal code immediately.
         Instead, we remember the signal and play with the allocation limit
*** byterun/signals.c.old	Tue May 18 14:32:56 1999
--- byterun/signals.c	Tue May 18 15:54:41 1999
***************
*** 76,81 ****
--- 76,82 ----
  static void execute_signal(int signal_number, int in_handler)
  {
    struct longjmp_buffer raise_buf, *saved_external_raise;
+   sigset_t saved_mask;
    int i;
  
    Assert (!async_signal_mode);
***************
*** 103,114 ****
        external_raise = &raise_buf;
    }
  
    sigaddset(&current_signal_mask, signal_number);
    sigprocmask(SIG_SETMASK, &current_signal_mask, NULL);
  
    callback(Field(signal_handlers, signal_number), Val_int(signal_number));
  
!   sigdelset(&current_signal_mask, signal_number);
    /* don't reset the signal mask if we're in the handler, so the handler
       doesn't nest unnecessarily */
    if (!in_handler)
--- 104,116 ----
        external_raise = &raise_buf;
    }
  
+   get_current_signal_mask(&saved_mask);
    sigaddset(&current_signal_mask, signal_number);
    sigprocmask(SIG_SETMASK, &current_signal_mask, NULL);
  
    callback(Field(signal_handlers, signal_number), Val_int(signal_number));
  
!   update_signal_mask(&saved_mask);
    /* don't reset the signal mask if we're in the handler, so the handler
       doesn't nest unnecessarily */
    if (!in_handler)
............

*** otherlibs/unix/execv.c.orig	Tue Sep  2 14:54:33 1997
--- otherlibs/unix/execv.c	Tue May 18 15:31:55 1999
***************
*** 15,21 ****
  #include <memory.h>
  #include "unixsupport.h"
  
! extern char ** cstringvect();
  
  value unix_execv(value path, value args)     /* ML */
  {
--- 15,21 ----
  #include <memory.h>
  #include "unixsupport.h"
  
! extern char ** cstringvect(value);
  
  value unix_execv(value path, value args)     /* ML */
  {
*** otherlibs/unix/execve.c.orig	Tue Sep  2 14:54:33 1997
--- otherlibs/unix/execve.c	Tue May 18 15:31:59 1999
***************
*** 15,21 ****
  #include <memory.h>
  #include "unixsupport.h"
  
! extern char ** cstringvect();
  
  value unix_execve(value path, value args, value env)     /* ML */
  {
--- 15,21 ----
  #include <memory.h>
  #include "unixsupport.h"
  
! extern char ** cstringvect(value);
  
  value unix_execve(value path, value args, value env)     /* ML */
  {
*** otherlibs/unix/execvp.c.orig	Tue Sep  2 14:54:34 1997
--- otherlibs/unix/execvp.c	Tue May 18 15:32:03 1999
***************
*** 15,21 ****
  #include <memory.h>
  #include "unixsupport.h"
  
! extern char ** cstringvect();
  extern char ** environ;
  
  value unix_execvp(value path, value args)     /* ML */
--- 15,21 ----
  #include <memory.h>
  #include "unixsupport.h"
  
! extern char ** cstringvect(value);
  extern char ** environ;
  
  value unix_execvp(value path, value args)     /* ML */
===== end patches =====




             reply	other threads:[~1999-05-19 17:52 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1999-05-19 17:44 Joerg Czeranski [this message]
1999-05-20  8:51 ` Xavier Leroy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='5vbInDAh9$2ip$1@joerch.org' \
    --to=jc@joerch.org \
    --cc=caml-list@inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox