pike.git / src / threads.c

version» Context lines:

pike.git/src/threads.c:1:   /*   || This file is part of Pike. For copyright information see COPYRIGHT.   || Pike is distributed under GPL, LGPL and MPL. See the file COPYING   || for more information. - || $Id: threads.c,v 1.240 2004/09/18 20:50:56 nilsson Exp $ + || $Id: threads.c,v 1.241 2004/12/30 13:50:35 grubba Exp $   */      #ifndef CONFIGURE_TEST   #include "global.h"      PMOD_EXPORT int num_threads = 1;   PMOD_EXPORT int threads_disabled = 0;   #endif /* !CONFIGURE_TEST */      /* #define PICKY_MUTEX */
pike.git/src/threads.c:846:       DEBUG_CHECK_THREAD();       Pike_interpreter.trace_level = default_t_flag;       THREADS_FPRINTF(0, (stderr,"new_thread_func(): Thread %p inited\n",    arg.thread_state));       if(SETJMP(back))    { -  if(throw_severity < THROW_EXIT) +  if(throw_severity <= THROW_ERROR)    call_handle_error();    if(throw_severity == THROW_EXIT)    {    pike_do_exit(throw_value.u.integer);    }    } else {    INT32 args=arg.args->size;    back.severity=THROW_EXIT;    push_array_items(arg.args);    arg.args=0;
pike.git/src/threads.c:1706:    Pike_sp++;    dmalloc_touch_svalue(Pike_sp-1);   }      static int num_pending_interrupts = 0;   static struct callback *thread_interrupt_callback = NULL;      static void check_thread_interrupt(struct callback *foo,    void *bar, void *gazonk)   { -  if (Pike_interpreter.thread_state->flags & THREAD_FLAG_INTR) { -  Pike_interpreter.thread_state->flags &= ~THREAD_FLAG_INTR; +  if (Pike_interpreter.thread_state->flags & THREAD_FLAG_SIGNAL_MASK) { +  if (Pike_interpreter.thread_state->flags & THREAD_FLAG_TERM) { +  throw_severity = THROW_THREAD_EXIT; +  } else { +  throw_severity = THROW_ERROR; +  } +  Pike_interpreter.thread_state->flags &= ~THREAD_FLAG_SIGNAL_MASK;    if (!--num_pending_interrupts) {    remove_callback(foo);    thread_interrupt_callback = NULL;    } -  +  if (throw_severity == THROW_ERROR) {    Pike_error("Interrupted.\n"); -  +  } else { +  push_int(-1); +  assign_svalue(&throw_value, Pike_sp-1); +  pike_throw();    }    } -  + }      /*! @decl void interrupt()    *! @decl void interrupt(string msg)    *!    *! Interrupt the thread with the message @[msg].    *!    *! @fixme    *! The argument @[msg] is currently ignored.    *!    *! @note    *! Interrupts are asynchronous, and are currently not queued.    */   static void f_thread_id_interrupt(INT32 args)   {    /* FIXME: The msg argument is not supported yet. */    pop_n_elems(args);    -  if (!(THIS_THREAD->flags & THREAD_FLAG_INTR)) { +  if (!(THIS_THREAD->flags & THREAD_FLAG_SIGNAL_MASK)) {    THIS_THREAD->flags |= THREAD_FLAG_INTR;    num_pending_interrupts++;    if (!thread_interrupt_callback) {    thread_interrupt_callback =    add_to_callback(&evaluator_callbacks, check_thread_interrupt, 0, 0);    }    /* FIXME: Actually interrupt the thread. */    }    push_int(0);   }    -  + /*! @decl void kill() +  *! +  *! Interrupt the thread, and terminate it. +  *! +  *! @note +  *! Interrupts are asynchronous, and are currently not queued. +  */ + static void f_thread_id_kill(INT32 args) + { +  pop_n_elems(args); +  +  if (!(THIS_THREAD->flags & THREAD_FLAG_SIGNAL_MASK)) { +  num_pending_interrupts++; +  if (!thread_interrupt_callback) { +  thread_interrupt_callback = +  add_to_callback(&evaluator_callbacks, check_thread_interrupt, 0, 0); +  } +  /* FIXME: Actually interrupt the thread. */ +  } +  THIS_THREAD->flags |= THREAD_FLAG_TERM; +  push_int(0); + } +    void init_thread_obj(struct object *o)   {    MEMSET(&THIS_THREAD->state, 0, sizeof(struct Pike_interpreter));    THIS_THREAD->thread_obj = Pike_fp->current_object;    THIS_THREAD->swapped = 0;    THIS_THREAD->status=THREAD_NOT_STARTED;    THIS_THREAD->flags = 0;    THIS_THREAD->result.type = T_INT;    THIS_THREAD->result.subtype = NUMBER_UNDEFINED;    THIS_THREAD->result.u.integer = 0;    co_init(& THIS_THREAD->status_change);    THIS_THREAD->thread_local=NULL;   #if CPU_TIME_IS_THREAD_LOCAL == PIKE_YES    THIS_THREAD->auto_gc_time = 0;   #endif   }         void exit_thread_obj(struct object *o)   { -  if (THIS_THREAD->flags & THREAD_FLAG_INTR) { -  Pike_interpreter.thread_state->flags &= ~THREAD_FLAG_INTR; +  if (THIS_THREAD->flags & THREAD_FLAG_SIGNAL_MASK) { +  Pike_interpreter.thread_state->flags &= ~THREAD_FLAG_SIGNAL_MASK;    if (!--num_pending_interrupts) {    remove_callback(thread_interrupt_callback);    thread_interrupt_callback = NULL;    }    }    if(THIS_THREAD->thread_local != NULL) {    free_mapping(THIS_THREAD->thread_local);    THIS_THREAD->thread_local = NULL;    }    co_destroy(& THIS_THREAD->status_change);
pike.git/src/threads.c:2195:    ADD_FUNCTION("create",f_thread_create,    tFuncV(tNone,tMixed,tVoid),    ID_STATIC);    ADD_FUNCTION("backtrace",f_thread_backtrace,tFunc(tNone,tArray),0);    ADD_FUNCTION("wait",f_thread_id_result,tFunc(tNone,tMix),0);    ADD_FUNCTION("status",f_thread_id_status,tFunc(tNone,tInt),0);    ADD_FUNCTION("_sprintf",f_thread_id__sprintf,tFunc(tNone,tStr),0);    ADD_FUNCTION("id_number",f_thread_id_id_number,tFunc(tNone,tInt),0);    ADD_FUNCTION("interrupt", f_thread_id_interrupt,    tFunc(tOr(tVoid,tStr), tVoid), 0); +  ADD_FUNCTION("kill", f_thread_id_kill, tFunc(tNone, tVoid), 0);    set_gc_recurse_callback(thread_was_recursed);    set_gc_check_callback(thread_was_checked);    set_init_callback(init_thread_obj);    set_exit_callback(exit_thread_obj);    thread_id_prog=Pike_compiler->new_program;    thread_id_prog->flags |= PROGRAM_NO_EXPLICIT_DESTRUCT;    add_ref(thread_id_prog);    end_class("thread_id", 0);       /* Backward compat... */