[INTERPRETER]
* BUG: Handle errors occuring while waiting for a process correctly now. * NEW: Process.Wait() now can take an optional timeout argument, in milliseconds. * BUG: Handle errors occuring while waiting for a task correctly now. git-svn-id: svn://localhost/gambas/trunk@5102 867c0c6c-44f3-4631-809d-bfa615b0a4ec
This commit is contained in:
parent
f3f10a4167
commit
1ab3b111c5
@ -844,14 +844,12 @@ CPROCESS *CPROCESS_create(int mode, void *cmd, char *name, CARRAY *env)
|
||||
return process;
|
||||
}
|
||||
|
||||
static CPROCESS *_error_CPROCESS_wait_for_process;
|
||||
|
||||
static void error_CPROCESS_wait_for()
|
||||
static void error_CPROCESS_wait_for(CPROCESS *process)
|
||||
{
|
||||
OBJECT_UNREF(_error_CPROCESS_wait_for_process, "CPROCESS_wait_for");
|
||||
OBJECT_UNREF(process, "CPROCESS_wait_for");
|
||||
}
|
||||
|
||||
void CPROCESS_wait_for(CPROCESS *process)
|
||||
void CPROCESS_wait_for(CPROCESS *process, int timeout)
|
||||
{
|
||||
int ret;
|
||||
int sigfd;
|
||||
@ -861,19 +859,20 @@ void CPROCESS_wait_for(CPROCESS *process)
|
||||
#endif
|
||||
|
||||
OBJECT_REF(process, "CPROCESS_wait_for");
|
||||
_error_CPROCESS_wait_for_process = process;
|
||||
|
||||
sigfd = SIGNAL_get_fd();
|
||||
|
||||
ON_ERROR(error_CPROCESS_wait_for)
|
||||
ON_ERROR_1(error_CPROCESS_wait_for, process)
|
||||
{
|
||||
while (process->running)
|
||||
{
|
||||
ret = WATCH_process(sigfd, process->out);
|
||||
ret = WATCH_process(sigfd, process->out, timeout);
|
||||
if (ret & WP_OUTPUT)
|
||||
callback_write(process->out, GB_WATCH_READ, process);
|
||||
if (ret & WP_END)
|
||||
SIGNAL_raise_callbacks(sigfd, GB_WATCH_READ, 0);
|
||||
if (ret & WP_TIMEOUT)
|
||||
break;
|
||||
if (ret == 0)
|
||||
usleep(1000);
|
||||
}
|
||||
@ -1043,9 +1042,9 @@ BEGIN_PROPERTY(Process_LastValue)
|
||||
|
||||
END_PROPERTY
|
||||
|
||||
BEGIN_METHOD_VOID(Process_Wait)
|
||||
BEGIN_METHOD(Process_Wait, GB_FLOAT timeout)
|
||||
|
||||
CPROCESS_wait_for(THIS);
|
||||
CPROCESS_wait_for(THIS, (int)(VARGOPT(timeout, 0.0) * 1000));
|
||||
|
||||
END_METHOD
|
||||
|
||||
@ -1075,7 +1074,7 @@ GB_DESC NATIVE_Process[] =
|
||||
|
||||
GB_METHOD("Kill", NULL, Process_Kill, NULL),
|
||||
GB_METHOD("Signal", NULL, Process_Signal, NULL),
|
||||
GB_METHOD("Wait", NULL, Process_Wait, NULL),
|
||||
GB_METHOD("Wait", NULL, Process_Wait, "[(Timeout)f]"),
|
||||
|
||||
GB_EVENT("Read", NULL, NULL, &EVENT_Read),
|
||||
GB_EVENT("Error", NULL, "(Error)s", &EVENT_Error),
|
||||
|
@ -71,6 +71,6 @@ enum
|
||||
};
|
||||
|
||||
CPROCESS *CPROCESS_create(int mode, void *cmd, char *name, CARRAY *env);
|
||||
void CPROCESS_wait_for(CPROCESS *process);
|
||||
void CPROCESS_wait_for(CPROCESS *process, int timeout);
|
||||
|
||||
#endif
|
||||
|
@ -479,20 +479,32 @@ BEGIN_METHOD_VOID(Task_Stop)
|
||||
|
||||
END_METHOD
|
||||
|
||||
static void error_Task_Wait(CTASK *task)
|
||||
{
|
||||
OBJECT_UNREF(task, "Task_Wait");
|
||||
}
|
||||
|
||||
BEGIN_METHOD_VOID(Task_Wait)
|
||||
|
||||
OBJECT_REF(THIS, "Task_Wait");
|
||||
|
||||
//printf("Task_Wait: %p\n", THIS); fflush(stdout);
|
||||
for(;;)
|
||||
|
||||
ON_ERROR_1(error_Task_Wait, THIS)
|
||||
{
|
||||
//printf("GB_Wait\n"); fflush(stdout);
|
||||
GB_Wait(0);
|
||||
//printf("stopped = %d\n", THIS->stopped); fflush(stdout);
|
||||
if (THIS->stopped)
|
||||
break;
|
||||
//printf("sleep\n"); fflush(stdout);
|
||||
sleep(10);
|
||||
for(;;)
|
||||
{
|
||||
//printf("GB_Wait\n"); fflush(stdout);
|
||||
GB_Wait(0);
|
||||
//printf("stopped = %d\n", THIS->stopped); fflush(stdout);
|
||||
if (THIS->stopped)
|
||||
break;
|
||||
//printf("sleep\n"); fflush(stdout);
|
||||
sleep(10);
|
||||
}
|
||||
}
|
||||
END_ERROR
|
||||
|
||||
OBJECT_UNREF(_object, "Task_Wait");
|
||||
|
||||
END_METHOD
|
||||
|
@ -74,7 +74,7 @@ void STREAM_exit(void)
|
||||
STREAM_close(&_temp_stream);
|
||||
}
|
||||
|
||||
#define wait_for_fd_ready_to_read(_fd) WATCH_process(_fd, -1)
|
||||
#define wait_for_fd_ready_to_read(_fd) WATCH_process(_fd, -1, 0)
|
||||
|
||||
bool STREAM_in_archive(const char *path)
|
||||
{
|
||||
|
@ -158,7 +158,7 @@ void SUBR_exec(ushort code)
|
||||
_error_subr_exec_process = process;
|
||||
ON_ERROR(error_subr_exec)
|
||||
{
|
||||
CPROCESS_wait_for(process);
|
||||
CPROCESS_wait_for(process, 0);
|
||||
}
|
||||
END_ERROR
|
||||
|
||||
|
@ -640,10 +640,11 @@ void WATCH_wait(int wait)
|
||||
}
|
||||
}
|
||||
|
||||
int WATCH_process(int fd_end, int fd_output)
|
||||
int WATCH_process(int fd_end, int fd_output, int timeout)
|
||||
{
|
||||
fd_set rfd;
|
||||
int ret, fd_max;
|
||||
struct timeval tv;
|
||||
|
||||
fd_max = fd_end > fd_output ? fd_end : fd_output;
|
||||
|
||||
@ -654,7 +655,18 @@ int WATCH_process(int fd_end, int fd_output)
|
||||
if (fd_output >= 0)
|
||||
FD_SET(fd_output, &rfd);
|
||||
|
||||
ret = select(fd_max + 1, &rfd, NULL, NULL, NULL);
|
||||
if (timeout > 0)
|
||||
{
|
||||
tv.tv_sec = timeout / 1000;
|
||||
tv.tv_usec = (timeout % 1000) * 1000;
|
||||
ret = select(fd_max + 1, &rfd, NULL, NULL, &tv);
|
||||
if (ret == 0)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = select(fd_max + 1, &rfd, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
if (ret > 0)
|
||||
break;
|
||||
@ -662,7 +674,7 @@ int WATCH_process(int fd_end, int fd_output)
|
||||
break;
|
||||
}
|
||||
|
||||
ret = WP_NOTHING;
|
||||
ret = timeout > 0 ? WP_TIMEOUT : WP_NOTHING;
|
||||
|
||||
if (FD_ISSET(fd_end, &rfd)) ret += WP_END;
|
||||
if (fd_output >= 0 && FD_ISSET(fd_output, &rfd)) ret += WP_OUTPUT;
|
||||
|
@ -41,7 +41,8 @@ enum {
|
||||
enum {
|
||||
WP_NOTHING = 0,
|
||||
WP_END = 1,
|
||||
WP_OUTPUT = 2
|
||||
WP_OUTPUT = 2,
|
||||
WP_TIMEOUT = 4
|
||||
};
|
||||
|
||||
typedef
|
||||
@ -70,7 +71,7 @@ bool WATCH_one_loop(int);
|
||||
void WATCH_loop(void);
|
||||
void WATCH_wait(int);
|
||||
int WATCH_loop_signal(const sigset_t *sig);
|
||||
int WATCH_process(int fd_end, int fd_output);
|
||||
int WATCH_process(int fd_end, int fd_output, int timeout);
|
||||
void WATCH_timer(void *t, int on);
|
||||
double WATCH_get_timeout(GB_TIMER *timer);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user