Skip to content
Commits on Source (2)
  • gambas's avatar
    Active file descriptor watches and active timers are now automatically... · a0bcf85b
    gambas authored
    Active file descriptor watches and active timers are now automatically transferred to the component declaring a custom event loop.
    
    [INTERPRETER]
    * BUG: Active file descriptor watches and active timers are now automatically transferred to the component declaring a custom event loop. Consequently, a process started before the declaration of the event loop will have its termination signal correctly catched.
    * NEW: Use waitpid() instead of wait4().
    
    [GB.GTK]
    * BUG: Declare the event loop hook last so that active file descriptor watches and active transfer are automatically transferred.
    
    [GB.GTK3]
    * BUG: Declare the event loop hook last so that active file descriptor watches and active transfer are automatically transferred.
    
    [GB.QT4]
    * BUG: Declare the event loop hook last so that active file descriptor watches and active transfer are automatically transferred.
    
    [GB.QT5]
    * BUG: Declare the event loop hook last so that active file descriptor watches and active transfer are automatically transferred.
    a0bcf85b
  • gambas's avatar
    Merge branch 'master' of gitlab.com:gambas/gambas · dd336c20
    gambas authored
    dd336c20
......@@ -209,12 +209,12 @@ int EXPORT GB_INIT(void)
GB.Hook(GB_HOOK_QUIT, (void *)my_quit);
_old_hook_main = GB.Hook(GB_HOOK_MAIN, (void *)my_main);
GB.Hook(GB_HOOK_WAIT, (void *)my_wait);
GB.Hook(GB_HOOK_LOOP, (void *)my_loop);
GB.Hook(GB_HOOK_TIMER,(void *)my_timer);
GB.Hook(GB_HOOK_WATCH,(void *)my_watch);
GB.Hook(GB_HOOK_POST,(void*)my_post);
GB.Hook(GB_HOOK_ERROR,(void*)my_error);
GB.Hook(GB_HOOK_LANG,(void*)my_lang);
GB.Hook(GB_HOOK_LOOP, (void *)my_loop);
GB.Component.Load("gb.draw");
GB.Component.Load("gb.image");
......
......@@ -35,7 +35,7 @@ void CWatch::watch(int fd, int type, GB_WATCH_CALLBACK callback, intptr_t param)
{
CWatch *watch;
//qDebug("CWatch::watch: %d %d", fd, type);
//qDebug("CWatch::watch: %d %d %p", fd, type, callback);
switch (type)
{
......
......@@ -1180,11 +1180,11 @@ static void QT_Init(void)
if (env && atoi(env) != 0)
MAIN_key_debug = TRUE;
GB.Hook(GB_HOOK_LOOP, (void *)hook_loop);
GB.Hook(GB_HOOK_WAIT, (void *)hook_wait);
GB.Hook(GB_HOOK_TIMER, (void *)hook_timer);
GB.Hook(GB_HOOK_WATCH, (void *)hook_watch);
GB.Hook(GB_HOOK_POST, (void *)hook_post);
GB.Hook(GB_HOOK_LOOP, (void *)hook_loop);
init = true;
}
......
......@@ -440,6 +440,15 @@ void *GB_Hook(int type, void *hook)
if (hook)
phook[type] = hook;
type++;
if (type == GB_HOOK_LOOP && !old_hook)
{
if (phook[GB_HOOK_WATCH])
WATCH_transfer_watch();
if (phook[GB_HOOK_TIMER])
WATCH_transfer_timer();
}
return old_hook;
}
......
......@@ -859,12 +859,13 @@ void CPROCESS_check(void *_object)
static bool wait_child(CPROCESS *process)
{
int status;
int ret;
#ifdef DEBUG_ME
fprintf(stderr, "wait_child: check process %d\n", process->pid);
#endif
if (wait4(process->pid, &status, WNOHANG, NULL) == process->pid)
if ((ret = waitpid(process->pid, &status, WNOHANG)) == process->pid)
{
process->status = status;
process->wait = TRUE;
......@@ -877,23 +878,18 @@ static bool wait_child(CPROCESS *process)
return TRUE;
}
else
{
#ifdef DEBUG_ME
fprintf(stderr, "wait_child: waitpid() has returned %d\n", ret);
#endif
return FALSE;
}
}
static void callback_child(int signum, intptr_t data)
{
CPROCESS *process, *next;
//int buffer;
#if 0
for(;;)
{
if (read(fd, (char *)&buffer, 1) == 1)
break;
if (errno != EINTR)
ERROR_panic("Cannot read from SIGCHLD pipe: %s", strerror(errno));
}
#endif
#ifdef DEBUG_ME
fprintf(stderr, ">> callback_child\n");
......@@ -906,7 +902,7 @@ static void callback_child(int signum, intptr_t data)
stop_process(process);
process = next;
}
throw_last_child_error();
#ifdef DEBUG_ME
......
......@@ -196,6 +196,10 @@ void SIGNAL_raise_callbacks(int fd, int type, void *data)
return;
}
#if DEBUG_ME
fprintf(stderr, "SIGNAL_raise_callbacks: signum = %d\n", signum);
#endif
handler = find_handler(signum);
if (!handler)
{
......
......@@ -336,20 +336,6 @@ static int find_max_fd(void)
return max;
}
/*static void ensure_watch_index(int fd)
{
int i;
int count = ARRAY_count(watch_index);
//fprintf(stderr, "ensure_watch_index: %d (%d)\n", fd, count);
if (fd < count)
return;
ARRAY_add_many(&watch_index, fd - count + 1);
for (i = count; i <= fd; i++)
watch_index[i] = -1;
}*/
static WATCH_CALLBACK *watch_create_callback(int fd)
{
......@@ -384,22 +370,19 @@ static WATCH_CALLBACK *watch_create_callback(int fd)
}
static void watch_delete_callback(int fd)
static void watch_delete_callback(int pos)
{
WATCH_CALLBACK *wcb;
int pos;
int fd;
#if DEBUG_WATCH
fprintf(stderr, "watch_delete_callback: %d (%d)\n", fd, _do_not_really_delete_callback);
#endif
pos = watch_find_callback(fd);
if (pos < 0)
return;
//watch_index[fd] = -1;
wcb = &watch_callback[pos];
fd = wcb->fd,
wcb->fd = -1;
watch_fd(fd, GB_WATCH_READ, FALSE);
watch_fd(fd, GB_WATCH_WRITE, FALSE);
......@@ -422,6 +405,14 @@ static void watch_delete_callback(int fd)
}
static void watch_delete_callback_from_fd(int fd)
{
int pos = watch_find_callback(fd);
if (pos >= 0)
watch_delete_callback(pos);
}
void WATCH_watch(int fd, int type, void *callback, intptr_t param)
{
WATCH_CALLBACK *wcb;
......@@ -434,7 +425,7 @@ void WATCH_watch(int fd, int type, void *callback, intptr_t param)
}
if (type == GB_WATCH_NONE)
watch_delete_callback(fd);
watch_delete_callback_from_fd(fd);
else
{
wcb = watch_create_callback(fd);
......@@ -454,7 +445,7 @@ void WATCH_watch(int fd, int type, void *callback, intptr_t param)
#endif
if (!wcb->callback_read && !wcb->callback_write)
watch_delete_callback(fd);
watch_delete_callback_from_fd(fd);
else
{
watch_fd(fd, GB_WATCH_READ, wcb->callback_read != NULL);
......@@ -463,6 +454,36 @@ void WATCH_watch(int fd, int type, void *callback, intptr_t param)
}
}
void WATCH_transfer_watch(void)
{
WATCH_CALLBACK *wcb;
int i;
for (i = 0; i < ARRAY_count(watch_callback); i++)
{
wcb = &watch_callback[i];
if (wcb->callback_read) HOOK(watch)(wcb->fd, GB_WATCH_READ, wcb->callback_read, wcb->param_read);
if (wcb->callback_write) HOOK(watch)(wcb->fd, GB_WATCH_WRITE, wcb->callback_write, wcb->param_write);
}
ARRAY_delete(&watch_callback);
}
void WATCH_transfer_timer(void)
{
WATCH_TIMER *wt;
int i;
for (i = 0; i < ARRAY_count(_timers); i++)
{
wt = &_timers[i];
HOOK(timer)((GB_TIMER *)wt->timer, TRUE);
}
ARRAY_delete(&_timers);
}
static void raise_callback(fd_set *rfd, fd_set *wfd)
{
......
......@@ -59,6 +59,8 @@ typedef
void WATCH_init(void);
void WATCH_exit(void);
void WATCH_transfer_watch(void);
void WATCH_transfer_timer(void);
void WATCH_watch(int fd, int flag, void *callback, intptr_t param);
bool WATCH_one_loop(int);
......
......@@ -102,6 +102,7 @@ Public Sub Wait() As String
If Jit.Debug Then Error "gb.jit: waiting for compilation of '"; Name; "'..."
$hProcess.Wait
If Jit.Debug Then Error "gb.jit: compilation of '"; Name; "' is available"
If Not Exist(PathSO) Then
Error "gb.jit: error: unable to compile JIT code of '"; Name; "':"
......