From 1741274a34fcd230a7d58383f0af19764e5b027d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Minisini?= Date: Sun, 26 Aug 2012 16:26:53 +0000 Subject: [PATCH] [INTERPRETER] * NEW: Task.Value now raises an error if the background task has failed for any reason. Otherwise it normally returns the background task return value. * BUG: Background tasks do not interfere with the debugger anymore. [GB.TASK] * NEW: The component has been moved inside the interpreter. git-svn-id: svn://localhost/gambas/trunk@5081 867c0c6c-44f3-4631-809d-bfa615b0a4ec --- app/src/gambas3/.lang/.pot | 4 - .../gambas3/.src/Component/CComponent.class | 2 +- app/src/gambas3/.src/Exported/Editor.class | 3 +- main/configure.ac | 1 - main/gbx/Makefile.am | 2 + main/gbx/gbx_c_task.c | 535 ++++++++++++++++++ main/gbx/gbx_c_task.h | 57 ++ main/gbx/gbx_class_info.c | 90 +-- main/gbx/gbx_class_init.c | 4 +- main/gbx/gbx_exec.c | 1 + main/gbx/gbx_exec.h | 45 +- 11 files changed, 669 insertions(+), 75 deletions(-) create mode 100644 main/gbx/gbx_c_task.c create mode 100644 main/gbx/gbx_c_task.h diff --git a/app/src/gambas3/.lang/.pot b/app/src/gambas3/.lang/.pot index f8f2f3007..844753227 100644 --- a/app/src/gambas3/.lang/.pot +++ b/app/src/gambas3/.lang/.pot @@ -258,10 +258,6 @@ msgstr "" msgid "Signals management" msgstr "" -#: CComponent.class:134 -msgid "Background tasks management" -msgstr "" - #: CComponent.class:135 msgid "Video capture" msgstr "" diff --git a/app/src/gambas3/.src/Component/CComponent.class b/app/src/gambas3/.src/Component/CComponent.class index cbd9f4908..20ac54751 100644 --- a/app/src/gambas3/.src/Component/CComponent.class +++ b/app/src/gambas3/.src/Component/CComponent.class @@ -131,7 +131,7 @@ Static Private Sub InitComponentNames() $cName["gb.sdl.sound"] = ("SDL sound & CD-ROM management") $cName["gb.settings"] = ("Application settings management") $cName["gb.signal"] = ("Signals management") - $cName["gb.task"] = ("Background tasks management") + '$cName["gb.task"] = ("Background tasks management") $cName["gb.v4l"] = ("Video capture") $cName["gb.vb"] = ("Visual Basic compatibility") $cName["gb.libxml"] = ("XML tools based on libxml") diff --git a/app/src/gambas3/.src/Exported/Editor.class b/app/src/gambas3/.src/Exported/Editor.class index 67237f417..09164be05 100644 --- a/app/src/gambas3/.src/Exported/Editor.class +++ b/app/src/gambas3/.src/Exported/Editor.class @@ -192,7 +192,7 @@ Public Sub ShowMessageLabel(sStr As String, X As Integer, Y As Integer, Optional $hLabel.Padding = 2 $hLabel.Wrap = False $hLabelTimer = New Timer As "LabelTimer" - $hLabelTimer.Delay = 5000 + $hLabelTimer.Delay = 10000 Endif X = Me.ScreenX + X - $hLabel.Parent.ScreenX @@ -211,6 +211,7 @@ Public Sub ShowMessageLabel(sStr As String, X As Integer, Y As Integer, Optional $hLabel.Show $hLabel.Raise + $hLabelTimer.Stop $hLabelTimer.Start Me.SetFocus diff --git a/main/configure.ac b/main/configure.ac index 156d18498..76b4883ae 100644 --- a/main/configure.ac +++ b/main/configure.ac @@ -112,7 +112,6 @@ lib/image.effect/Makefile \ lib/signal/Makefile \ lib/complex/Makefile \ lib/adt/Makefile \ -lib/task/Makefile \ ]) AC_OUTPUT diff --git a/main/gbx/Makefile.am b/main/gbx/Makefile.am index 577e7ec41..b235598e5 100644 --- a/main/gbx/Makefile.am +++ b/main/gbx/Makefile.am @@ -70,6 +70,7 @@ gbx3_SOURCES = \ gbx_c_subcollection.h gbx_c_subcollection.c \ gbx_c_string.h gbx_c_string.c \ gbx_c_observer.h gbx_c_observer.c \ + gbx_c_task.h gbx_c_task.c \ gbx_component.h gbx_component.c \ gbx_extern.h gbx_extern.c \ gbx_c_enum.h gbx_c_enum.c \ @@ -94,4 +95,5 @@ gb_la_SOURCES = \ gbx_c_subcollection.h gbx_c_subcollection.c \ gbx_c_enum.h gbx_c_enum.c \ gbx_c_timer.h gbx_c_timer.c \ + gbx_c_task.h gbx_c_task.c \ gbx_class_info.c diff --git a/main/gbx/gbx_c_task.c b/main/gbx/gbx_c_task.c new file mode 100644 index 000000000..059f7f9b3 --- /dev/null +++ b/main/gbx/gbx_c_task.c @@ -0,0 +1,535 @@ +/*************************************************************************** + + gbx_c_task.c + + (c) 2000-2012 Benoît Minisini + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. + +***************************************************************************/ + +#define __GBX_C_TASK_C + +#include "gbx_info.h" + +#ifndef GBX_INFO + +#include +#include +#include + +#include "gb_common.h" +#include "gb_list.h" +#include "gb_file.h" +#include "gb_error.h" +#include "gbx_api.h" +#include "gbx_exec.h" +#include "gbx_string.h" +#include "gbx_signal.h" +#include "gbx_event.h" + +#include "gbx_c_task.h" + +DECLARE_EVENT(EVENT_Read); +DECLARE_EVENT(EVENT_Error); +DECLARE_EVENT(EVENT_Kill); + +enum { + CHILD_OK = 0, + CHILD_ERROR = 1, + CHILD_STDOUT = 2, + CHILD_STDERR = 3, + CHILD_RETURN = 4 +}; + +static SIGNAL_CALLBACK *_signal_handler = NULL; +static CTASK *_task_list = NULL; +static int _task_count = 0; + +//------------------------------------------------------------------------- + +static void stop_task(CTASK *_object); + +static void has_forked(void) +{ + FILE_init(); + EXEC_debug = FALSE; + EXEC_task = TRUE; +} + +static void callback_child(int signum, intptr_t data) +{ + CTASK *_object, *next; + int status; + + _object = _task_list; + while (_object) + { + next = THIS->list.next; + if (wait4(THIS->pid, &status, WNOHANG, NULL) == THIS->pid) + { + THIS->status = status; + stop_task(THIS); + } + _object = next; + } +} + +static int get_readable(int fd) +{ + int len; + + if (ioctl(fd, FIONREAD, &len) < 0 || len <= 0) + return 0; + else + return len; +} + +static void callback_write(int fd, int type, CTASK *_object) +{ + int len; + char *data; + char *p; + int n; + + //fprintf(stderr, "callback_write: %d %p\n", fd, THIS); + + len = get_readable(fd); + + data = STRING_new(NULL, len); + p = data; + + while (len > 0) + { + n = read(fd, p, len); + if (n < 0) + { + if (errno == EINTR) + continue; + else + break; + } + len -= n; + p += n; + } + + GB_Raise(THIS, EVENT_Read, 1, GB_T_STRING, data, STRING_length(data) - len); + + STRING_free(&data); +} + + +static int callback_error(int fd, int type, CTASK *_object) +{ + char buffer[256]; + int n; + + //fprintf(stderr, "callback_error: %d %p\n", fd, THIS); + + n = read(fd, buffer, sizeof(buffer)); + + if (n <= 0) + return TRUE; + + GB_Raise(THIS, EVENT_Error, 1, GB_T_STRING, buffer, n); + return FALSE; +} + +static bool create_return_directory(void) +{ + static bool mkdir_done = FALSE; + + char buf[PATH_MAX]; + + if (mkdir_done) + return FALSE; + + sprintf(buf, RETURN_DIR_PATTERN, getuid(), getpid()); + + if (mkdir(buf, S_IRWXU) != 0) + { + GB_Error("Cannot create task return directory"); + return TRUE; + } + + mkdir_done = TRUE; + return FALSE; +} + +static void init_task(void) +{ + _task_count++; + + if (_task_count > 1) + return; + + _signal_handler = SIGNAL_register(SIGCHLD, callback_child, 0); +} + +static void exit_task(void) +{ + _task_count--; + + if (_task_count > 0) + return; + + SIGNAL_unregister(SIGCHLD, _signal_handler); + _signal_handler = NULL; +} + +static void prepare_task(CTASK *_object) +{ + THIS->fd_out = -1; + THIS->fd_err = -1; +} + +static bool start_task(CTASK *_object) +{ + const char *err = NULL; + pid_t pid; + sigset_t sig, old; + GB_FUNCTION func; + int fd_out[2], fd_err[2]; + bool has_read, has_error; + GB_VALUE *ret; + char buf[PATH_MAX]; + FILE *f; + + init_task(); + + LIST_insert(&_task_list, THIS, &THIS->list); + + // Create pipes + + has_read = GB_CanRaise(THIS, EVENT_Read); + has_error = GB_CanRaise(THIS, EVENT_Error); + + if (has_read && pipe(fd_out) != 0) + goto __ERROR; + + if (has_error && pipe(fd_err) != 0) + goto __ERROR; + + // Block SIGCHLD + + sigemptyset(&sig); + + sigaddset(&sig, SIGCHLD); + sigprocmask(SIG_BLOCK, &sig, &old); + + pid = fork(); + if (pid == (-1)) + { + stop_task(THIS); + sigprocmask(SIG_SETMASK, &old, &sig); + goto __ERROR; + } + + if (pid) + { + THIS->pid = pid; + + if (has_read) + { + close(fd_out[1]); + THIS->fd_out = fd_out[0]; + + GB_Watch(THIS->fd_out, GB_WATCH_READ, (void *)callback_write, (intptr_t)THIS); + } + + if (has_error) + { + close(fd_err[1]); + THIS->fd_err = fd_err[0]; + + fcntl(THIS->fd_err, F_SETFL, fcntl(THIS->fd_err, F_GETFL) | O_NONBLOCK); + GB_Watch(THIS->fd_err, GB_WATCH_READ, (void *)callback_error, (intptr_t)THIS); + } + + sigprocmask(SIG_SETMASK, &old, &sig); + } + else // child task + { + THIS->child = TRUE; + THIS->pid = getpid(); + + has_forked(); + + sigprocmask(SIG_SETMASK, &old, &sig); + + if (has_read) + { + close(fd_out[0]); + + if (dup2(fd_out[1], STDOUT_FILENO) == -1) + exit(CHILD_STDOUT); + + setlinebuf(stdout); + } + + if (has_error) + { + close(fd_err[0]); + + if (dup2(fd_err[1], STDERR_FILENO) == -1) + exit(CHILD_STDERR); + + setlinebuf(stderr); + } + + GB_GetFunction(&func, THIS, "Main", "", NULL); + + TRY + { + ret = GB_Call(&func, 0, FALSE); + if (ret->type != GB_T_VOID) + { + sprintf(buf, RETURN_FILE_PATTERN, getuid(), getppid(), getpid()); + //fprintf(stderr, "serialize to: %s\n", buf); + GB_ReturnConvVariant(); + if (GB_Serialize(buf, ret)) + { + //fprintf(stderr, "gb.task: serialization has failed\n"); + exit(CHILD_RETURN); + } + } + } + CATCH + { + if (ERROR_current->info.code && ERROR_current->info.code != E_ABORT) + { + sprintf(buf, RETURN_FILE_PATTERN, getuid(), getppid(), getpid()); + f = fopen(buf, "w+"); + if (f) + { + ERROR_print_at(f, FALSE, FALSE); + fclose(f); + } + + exit(CHILD_ERROR); + } + } + END_TRY + + exit(CHILD_OK); + } + + return FALSE; + +__ERROR: + + // TODO: as the routine is posted, nobody will see the error! + if (!err) + err = strerror(errno); + fprintf(stderr, "gb.task: cannot run task: %s\n", err); + GB_Error("Cannot run task: &1", err); + + return TRUE; +} + +static void close_fd(int *pfd) +{ + int fd = *pfd; + + if (fd >= 0) + { + GB_Watch(fd, GB_WATCH_NONE, NULL, 0); + close(fd); + *pfd = -1; + } +} + +static void stop_task(CTASK *_object) +{ + int len; + + THIS->stopped = TRUE; + + // Flush standard error + if (THIS->fd_err >= 0) + while (callback_error(THIS->fd_err, 0, THIS) == 0); + + // Flush standard output + if (THIS->fd_out >= 0) + { + for(;;) + { + len = get_readable(THIS->fd_out); + if (len <= 0) + break; + + THIS->something_read = FALSE; + callback_write(THIS->fd_out, 0, THIS); + if (!THIS->something_read) + break; + } + } + + LIST_remove(&_task_list, THIS, &THIS->list); + + GB_Raise(THIS, EVENT_Kill, 0); + + close_fd(&THIS->fd_out); + close_fd(&THIS->fd_err); + + OBJECT_UNREF(_object, "stop_task"); + + exit_task(); +} + +//------------------------------------------------------------------------- + +BEGIN_METHOD_VOID(Task_new) + + GB_FUNCTION func; + + if (create_return_directory()) + return; + + if (GB_GetFunction(&func, THIS, "Main", "", NULL)) + return; + + prepare_task(THIS); + + OBJECT_REF(THIS, "Task_new"); + EVENT_post((GB_CALLBACK)start_task, (intptr_t)THIS); + +END_METHOD + + +BEGIN_PROPERTY(Task_Handle) + + GB_ReturnInteger(THIS->pid); + +END_PROPERTY + + +BEGIN_METHOD_VOID(Task_Stop) + + kill(THIS->pid, SIGKILL); + +END_METHOD + +BEGIN_METHOD_VOID(Task_Wait) + + for(;;) + { + GB_Wait(0); + if (THIS->stopped) + break; + sleep(10); + } + +END_METHOD + +BEGIN_PROPERTY(Task_Value) + + char path[PATH_MAX]; + GB_VALUE ret; + FILE_STAT info; + char *err = NULL; + int fd; + + if (!THIS->child && THIS->stopped) + { + sprintf(path, RETURN_FILE_PATTERN, getuid(), getpid(), THIS->pid); + + if (WIFEXITED(THIS->status)) + { + switch (WEXITSTATUS(THIS->status)) + { + case CHILD_OK: + + if (!GB_UnSerialize(path, &ret)) + { + unlink(path); + GB_ReturnVariant(&ret._variant.value); + return; + } + else + unlink(path); + + break; + + case CHILD_STDOUT: + + GB_Error("Unable to redirect task standard output"); + return; + + case CHILD_STDERR: + + GB_Error("Unable to redirect task error output"); + return; + + case CHILD_RETURN: + + GB_Error("Unable to serialize task return value"); + return; + + case CHILD_ERROR: + + FILE_stat(path, &info, FALSE); + + err = STRING_new_temp(NULL, info.size); + + fd = open(path, O_RDONLY); + if (fd < 0) goto __ERROR; + + STREAM_read_direct(fd, err, info.size); + close(fd); + + GB_Error("Task has failed: &1", err); + return; + } + } + else if (WIFSIGNALED(THIS->status)) + { + GB_Error("Task has aborted: &1", strsignal(WTERMSIG(THIS->status))); + return; + } + } + +__ERROR: + + GB_ReturnNull(); + GB_ReturnConvVariant(); + +END_PROPERTY + + +//------------------------------------------------------------------------- + +#endif + +GB_DESC TaskDesc[] = +{ + GB_DECLARE("Task", sizeof(CTASK)), GB_NOT_CREATABLE(), + + GB_METHOD("_new", NULL, Task_new, NULL), + //GB_METHOD("_free", NULL, Task_free, NULL), + + GB_PROPERTY_READ("Handle", "i", Task_Handle), + GB_PROPERTY_READ("Value", "v", Task_Value), + + GB_METHOD("Stop", NULL, Task_Stop, NULL), + GB_METHOD("Wait", NULL, Task_Wait, NULL), + + GB_EVENT("Read", NULL, "(Data)s", &EVENT_Read), + GB_EVENT("Error", NULL, "(Data)s", &EVENT_Error), + GB_EVENT("Kill", NULL, NULL, &EVENT_Kill), + + GB_END_DECLARE +}; diff --git a/main/gbx/gbx_c_task.h b/main/gbx/gbx_c_task.h new file mode 100644 index 000000000..aaa3e8e0a --- /dev/null +++ b/main/gbx/gbx_c_task.h @@ -0,0 +1,57 @@ +/*************************************************************************** + + gbx_c_task.h + + (c) 2000-2012 Benoît Minisini + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. + +***************************************************************************/ + +#ifndef __GBX_C_TASK_H +#define __GBX_C_TASK_H + +#include +#include + +#include "gambas.h" +#include "gb_file.h" +#include "gb_list.h" + +#ifndef __GBX_C_TASK_C +extern GB_DESC TaskDesc[]; +#endif + +typedef + struct { + GB_BASE ob; + LIST list; + pid_t pid; + int fd_out; + int fd_err; + int status; + volatile sig_atomic_t stopped; + unsigned something_read : 1; + unsigned child : 1; + } + CTASK; + +#define THIS ((CTASK *)_object) + +#define RETURN_DIR_PATTERN FILE_TEMP_DIR "/task" +#define RETURN_FILE_PATTERN FILE_TEMP_DIR "/task/%d" + +#endif diff --git a/main/gbx/gbx_class_info.c b/main/gbx/gbx_class_info.c index 1a2894465..a70e5e02e 100644 --- a/main/gbx/gbx_class_info.c +++ b/main/gbx/gbx_class_info.c @@ -319,50 +319,51 @@ static GB_DESC NATIVE_GambasLanguage[] = }; -EXTERN GB_DESC NATIVE_GambasLanguage[]; -EXTERN GB_DESC NATIVE_Gambas[]; -EXTERN GB_DESC NATIVE_Param[]; -EXTERN GB_DESC NATIVE_Enum[]; -EXTERN GB_DESC NATIVE_Symbol[]; -EXTERN GB_DESC NATIVE_Class[]; -EXTERN GB_DESC NATIVE_Classes[]; -EXTERN GB_DESC NATIVE_Component[]; -EXTERN GB_DESC NATIVE_Components[]; -EXTERN GB_DESC NATIVE_Object[]; -EXTERN GB_DESC NATIVE_Collection[]; -EXTERN GB_DESC NATIVE_Error[]; -EXTERN GB_DESC NATIVE_Stream[]; -EXTERN GB_DESC NATIVE_StreamLines[]; -EXTERN GB_DESC NATIVE_StatPerm[]; -EXTERN GB_DESC NATIVE_Stat[]; -EXTERN GB_DESC NATIVE_File[]; -EXTERN GB_DESC NATIVE_AppEnv[]; -EXTERN GB_DESC NATIVE_AppArgs[]; -EXTERN GB_DESC NATIVE_App[]; -EXTERN GB_DESC NATIVE_System[]; -EXTERN GB_DESC NATIVE_User[]; -EXTERN GB_DESC NATIVE_ArrayBounds[]; -EXTERN GB_DESC NATIVE_Array[]; -EXTERN GB_DESC NATIVE_Process[]; -EXTERN GB_DESC NATIVE_BooleanArray[]; -EXTERN GB_DESC NATIVE_ByteArray[]; -EXTERN GB_DESC NATIVE_ShortArray[]; -EXTERN GB_DESC NATIVE_IntegerArray[]; -EXTERN GB_DESC NATIVE_SingleArray[]; -EXTERN GB_DESC NATIVE_FloatArray[]; -EXTERN GB_DESC NATIVE_DateArray[]; -EXTERN GB_DESC NATIVE_StringArray[]; -EXTERN GB_DESC NATIVE_ObjectArray[]; -EXTERN GB_DESC NATIVE_VariantArray[]; -EXTERN GB_DESC NATIVE_TemplateArray[]; -EXTERN GB_DESC NATIVE_TemplateArrayOfStruct[]; -EXTERN GB_DESC NATIVE_LongArray[]; -EXTERN GB_DESC NATIVE_PointerArray[]; -EXTERN GB_DESC NATIVE_SubCollection[]; -EXTERN GB_DESC NATIVE_String[]; -EXTERN GB_DESC NATIVE_Timer[]; -EXTERN GB_DESC NATIVE_Observer[]; -EXTERN GB_DESC NATIVE_Proxy[]; +extern GB_DESC NATIVE_GambasLanguage[]; +extern GB_DESC NATIVE_Gambas[]; +extern GB_DESC NATIVE_Param[]; +extern GB_DESC NATIVE_Enum[]; +extern GB_DESC NATIVE_Symbol[]; +extern GB_DESC NATIVE_Class[]; +extern GB_DESC NATIVE_Classes[]; +extern GB_DESC NATIVE_Component[]; +extern GB_DESC NATIVE_Components[]; +extern GB_DESC NATIVE_Object[]; +extern GB_DESC NATIVE_Collection[]; +extern GB_DESC NATIVE_Error[]; +extern GB_DESC NATIVE_Stream[]; +extern GB_DESC NATIVE_StreamLines[]; +extern GB_DESC NATIVE_StatPerm[]; +extern GB_DESC NATIVE_Stat[]; +extern GB_DESC NATIVE_File[]; +extern GB_DESC NATIVE_AppEnv[]; +extern GB_DESC NATIVE_AppArgs[]; +extern GB_DESC NATIVE_App[]; +extern GB_DESC NATIVE_System[]; +extern GB_DESC NATIVE_User[]; +extern GB_DESC NATIVE_ArrayBounds[]; +extern GB_DESC NATIVE_Array[]; +extern GB_DESC NATIVE_Process[]; +extern GB_DESC NATIVE_BooleanArray[]; +extern GB_DESC NATIVE_ByteArray[]; +extern GB_DESC NATIVE_ShortArray[]; +extern GB_DESC NATIVE_IntegerArray[]; +extern GB_DESC NATIVE_SingleArray[]; +extern GB_DESC NATIVE_FloatArray[]; +extern GB_DESC NATIVE_DateArray[]; +extern GB_DESC NATIVE_StringArray[]; +extern GB_DESC NATIVE_ObjectArray[]; +extern GB_DESC NATIVE_VariantArray[]; +extern GB_DESC NATIVE_TemplateArray[]; +extern GB_DESC NATIVE_TemplateArrayOfStruct[]; +extern GB_DESC NATIVE_LongArray[]; +extern GB_DESC NATIVE_PointerArray[]; +extern GB_DESC NATIVE_SubCollection[]; +extern GB_DESC NATIVE_String[]; +extern GB_DESC TaskDesc[]; +extern GB_DESC NATIVE_Timer[]; +extern GB_DESC NATIVE_Observer[]; +extern GB_DESC NATIVE_Proxy[]; GB_DESC *GB_CLASSES[] EXPORT = { @@ -407,6 +408,7 @@ GB_DESC *GB_CLASSES[] EXPORT = NATIVE_PointerArray, NATIVE_SubCollection, NATIVE_String, + TaskDesc, NATIVE_Timer, NATIVE_Observer, //NATIVE_Proxy, diff --git a/main/gbx/gbx_class_init.c b/main/gbx/gbx_class_init.c index ed70f159c..d3acbb984 100644 --- a/main/gbx/gbx_class_init.c +++ b/main/gbx/gbx_class_init.c @@ -44,6 +44,7 @@ #include "gbx_c_string.h" #include "gbx_c_enum.h" #include "gbx_c_timer.h" +#include "gbx_c_task.h" #include "gbx_class.h" @@ -113,6 +114,7 @@ static const CLASS_INIT init_list[] = { NATIVE_System, NULL }, { NATIVE_User, NULL }, { NATIVE_String, NULL }, + { TaskDesc, NULL }, { NATIVE_Timer, &CLASS_Timer }, { NATIVE_Observer, &CLASS_Observer }, //{ NATIVE_Proxy, &CLASS_Proxy }, @@ -169,5 +171,3 @@ void CLASS_init_native(void) //CLASS_Proxy->is_observer = TRUE; //CLASS_Proxy->size += sizeof(OBJECT_EVENT); } - - diff --git a/main/gbx/gbx_exec.c b/main/gbx/gbx_exec.c index 20b7ed7ab..218c3e6e2 100644 --- a/main/gbx/gbx_exec.c +++ b/main/gbx/gbx_exec.c @@ -62,6 +62,7 @@ bool EXEC_big_endian; CENUM *EXEC_enum; bool EXEC_debug = FALSE; // debugging mode +bool EXEC_task = FALSE; // I am a background task bool EXEC_profile = FALSE; // profiling mode bool EXEC_profile_instr = FALSE; // profiling mode at instruction level const char *EXEC_profile_path = NULL; // profile file path diff --git a/main/gbx/gbx_exec.h b/main/gbx/gbx_exec.h index 8dd5692a7..83f6bdfb1 100644 --- a/main/gbx/gbx_exec.h +++ b/main/gbx/gbx_exec.h @@ -84,36 +84,37 @@ enum { #ifndef __GBX_EXEC_C -EXTERN STACK_CONTEXT EXEC_current; -EXTERN VALUE *SP; -EXTERN VALUE TEMP; -EXTERN VALUE RET; +extern STACK_CONTEXT EXEC_current; +extern VALUE *SP; +extern VALUE TEMP; +extern VALUE RET; -EXTERN VALUE *EXEC_super; +extern VALUE *EXEC_super; -EXTERN bool EXEC_debug; -EXTERN bool EXEC_profile; -EXTERN const char *EXEC_profile_path; -EXTERN bool EXEC_profile_instr; -EXTERN bool EXEC_arch; -EXTERN bool EXEC_fifo; -EXTERN const char *EXEC_fifo_name; -EXTERN bool EXEC_keep_library; +extern bool EXEC_debug; +extern bool EXEC_task; +extern bool EXEC_profile; +extern const char *EXEC_profile_path; +extern bool EXEC_profile_instr; +extern bool EXEC_arch; +extern bool EXEC_fifo; +extern const char *EXEC_fifo_name; +extern bool EXEC_keep_library; -EXTERN EXEC_HOOK EXEC_Hook; +extern EXEC_HOOK EXEC_Hook; -EXTERN CENUM *EXEC_enum; +extern CENUM *EXEC_enum; -EXTERN bool EXEC_big_endian; -EXTERN bool EXEC_main_hook_done; -EXTERN bool EXEC_got_error; +extern bool EXEC_big_endian; +extern bool EXEC_main_hook_done; +extern bool EXEC_got_error; -EXTERN const char EXEC_should_borrow[]; +extern const char EXEC_should_borrow[]; -EXTERN const char *EXEC_unknown_name; -EXTERN char EXEC_unknown_nparam; +extern const char *EXEC_unknown_name; +extern char EXEC_unknown_nparam; -EXTERN EXEC_GLOBAL EXEC; +extern EXEC_GLOBAL EXEC; #endif