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.238 2004/07/16 12:44:56 grubba Exp $ + || $Id: threads.c,v 1.239 2004/08/12 12:38:39 grubba Exp $   */      #ifndef CONFIGURE_TEST   #include "global.h" - RCSID("$Id: threads.c,v 1.238 2004/07/16 12:44:56 grubba Exp $"); + RCSID("$Id: threads.c,v 1.239 2004/08/12 12:38:39 grubba Exp $");      PMOD_EXPORT int num_threads = 1;   PMOD_EXPORT int threads_disabled = 0;   #endif /* !CONFIGURE_TEST */      /* #define PICKY_MUTEX */      #ifdef _REENTRANT      #ifndef CONFIGURE_TEST
pike.git/src/threads.c:1701:    (stderr,    "Thread->wait(): Waiting for thread %p (state:%d).\n",    th, th->status));    }       assign_svalue_no_free(Pike_sp, &th->result);    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 (!--num_pending_interrupts) { +  remove_callback(foo); +  thread_interrupt_callback = NULL; +  } +  Pike_error("Interrupted.\n"); +  } + } +  + /*! @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)) { +  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); + } +    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 (!--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);    th_destroy(& THIS_THREAD->id);    THIS_THREAD->thread_obj = NULL;   }      /*! @endclass
pike.git/src/threads.c:2142:    PIKE_MAP_VARIABLE("result", OFFSETOF(thread_state, result),    tMix, T_MIXED, 0);    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);    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... */