[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:
Benoît Minisini 2012-08-30 22:49:21 +00:00
parent f3f10a4167
commit 1ab3b111c5
7 changed files with 51 additions and 27 deletions

View File

@ -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),

View File

@ -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

View File

@ -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

View File

@ -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)
{

View File

@ -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

View File

@ -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;

View File

@ -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);