mirror of
https://github.com/YosysHQ/abc.git
synced 2026-08-30 01:29:01 +02:00
1. Replace system() with a function that responds to SIGINT. 2. Add functions to cleanup temporary files on SIGINT. 3. Fix bugs related to signal handling.
This commit is contained in:
+15
-27
@@ -25,8 +25,7 @@
|
||||
#include <main.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <hash.h>
|
||||
#include <hashPtr.h>
|
||||
#include "utilSignal.h"
|
||||
|
||||
int n_ands()
|
||||
{
|
||||
@@ -219,56 +218,44 @@ void pyabc_internal_register_command( char * sGroup, char * sName, int fChanges
|
||||
Cmd_CommandAdd( pAbc, sGroup, sName, (void*)pyabc_internal_abc_command_callback, fChanges);
|
||||
}
|
||||
|
||||
static Hash_Ptr_t* active_pid_hash = NULL;
|
||||
|
||||
void sigint_handler(int signum)
|
||||
static void sigint_handler(int signum)
|
||||
{
|
||||
int i;
|
||||
Hash_Ptr_Entry_t* pEntry;
|
||||
|
||||
assert( signum == SIGINT );
|
||||
|
||||
Hash_PtrForEachEntry(active_pid_hash, pEntry, i)
|
||||
{
|
||||
int pid = pEntry->key;
|
||||
kill(pid, SIGINT);
|
||||
}
|
||||
|
||||
Util_SignalCleanup();
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
void add_child_pid(int pid)
|
||||
{
|
||||
Hash_PtrWriteEntry(active_pid_hash, pid, NULL);
|
||||
Util_SignalAddChildPid(pid);
|
||||
}
|
||||
|
||||
void remove_child_pid(int pid)
|
||||
{
|
||||
Hash_PtrRemove(active_pid_hash, pid);
|
||||
Util_SignalRemoveChildPid(pid);
|
||||
}
|
||||
|
||||
static sigset_t old_procmask;
|
||||
|
||||
void block_sigint()
|
||||
{
|
||||
sigset_t set;
|
||||
sigemptyset(&set);
|
||||
sigaddset(&set, SIGINT);
|
||||
|
||||
sigprocmask(SIG_BLOCK, &set, &old_procmask);
|
||||
Util_SignalBlockSignals();
|
||||
}
|
||||
|
||||
void restore_sigint_block()
|
||||
{
|
||||
sigprocmask(SIG_SETMASK, &old_procmask, NULL);
|
||||
Util_SignalUnblockSignals();
|
||||
}
|
||||
|
||||
void reset_sigint_handler()
|
||||
{
|
||||
Util_SignalResetHandler();
|
||||
}
|
||||
|
||||
|
||||
%}
|
||||
|
||||
%init
|
||||
%{
|
||||
Abc_Start();
|
||||
active_pid_hash = Hash_PtrAlloc(1);
|
||||
Util_SignalStartHandler();
|
||||
signal(SIGINT, sigint_handler);
|
||||
%}
|
||||
|
||||
@@ -301,6 +288,7 @@ void block_sigint();
|
||||
void restore_sigint_block();
|
||||
void add_child_pid(int pid);
|
||||
void remove_child_pid(int pid);
|
||||
void reset_sigint_handler();
|
||||
|
||||
%pythoncode
|
||||
%{
|
||||
|
||||
@@ -83,6 +83,7 @@ Author: Baruch Sterin <[email protected]>
|
||||
"""
|
||||
|
||||
import os
|
||||
import errno
|
||||
import sys
|
||||
import pickle
|
||||
import signal
|
||||
@@ -90,6 +91,26 @@ from contextlib import contextmanager
|
||||
|
||||
import pyabc
|
||||
|
||||
def _waitpid(pid, flags):
|
||||
while True:
|
||||
try:
|
||||
res = os.waitpid(pid, flags)
|
||||
return res
|
||||
except OSError as e:
|
||||
if e.errno != errno.EINTR:
|
||||
raise
|
||||
|
||||
def _wait():
|
||||
while True:
|
||||
try:
|
||||
pid,rc = os.wait()
|
||||
return pid, rc
|
||||
except OSError as e:
|
||||
if e.errno != errno.EINTR:
|
||||
raise
|
||||
except Exceptions as e:
|
||||
raise
|
||||
|
||||
class _sigint_critical_section(object):
|
||||
def __init__(self):
|
||||
self.blocked = False
|
||||
@@ -132,7 +153,7 @@ class _splitter(object):
|
||||
with _sigint_critical_section() as cs:
|
||||
# wait for termination and update result
|
||||
for pid, _ in self.fds.iteritems():
|
||||
os.waitpid( pid, 0 )
|
||||
_waitpid( pid, 0 )
|
||||
pyabc.remove_child_pid(pid)
|
||||
self.results[pid] = None
|
||||
|
||||
@@ -164,6 +185,7 @@ class _splitter(object):
|
||||
|
||||
if pid == 0:
|
||||
# child process:
|
||||
pyabc.reset_sigint_handler()
|
||||
cs.release()
|
||||
os.close(pr)
|
||||
rc = self.child( pw, f)
|
||||
@@ -187,9 +209,12 @@ class _splitter(object):
|
||||
def get_next_result(self):
|
||||
|
||||
# wait for the next child process to terminate
|
||||
pid, rc = os.wait()
|
||||
pid, rc = _wait()
|
||||
assert pid in self.fds
|
||||
|
||||
with _sigint_critical_section() as cs:
|
||||
pyabc.remove_child_pid(pid)
|
||||
|
||||
# retrieve the pipe file descriptor1
|
||||
i, fd = self.fds[pid]
|
||||
del self.fds[pid]
|
||||
|
||||
Reference in New Issue
Block a user