pike.git / src / threads.c

version» Context lines:

pike.git/src/threads.c:2645:   static void init_rwmutex_obj(struct object *o)   {    co_init(&THIS_RWMUTEX->condition);   }      static void exit_rwmutex_obj(struct object *o)   {    co_destroy(&THIS_RWMUTEX->condition);   }    - /*! @decl ReadKey read_lock(int(0..1)|void recursive) + /*! @decl ReadKey read_lock()    *!    *! Obtain a lock for reading (shared lock).    *! -  *! @param recursive -  *! Support the same thread obtaining several locks -  *! (both read and write). -  *! +     *! @throws    *! Throws an error if the current thread already has -  *! a lock (read or write) unless @[recursive] is @expr{1@}. +  *! a lock (read or write).    *!    *! @seealso    *! @[write_lock()]    */   static void f_rwmutex_read_lock(INT32 args)   {    ref_push_object_inherit(Pike_fp->current_object,    Pike_fp->context -    Pike_fp->current_object->prog->inherits);    push_object(clone_object(rwmutex_rkey_program, 1));   }    - /*! @decl WriteKey write_lock(int(0..1)|void recursive) + /*! @decl WriteKey write_lock()    *!    *! Obtain a lock for writing (exclusive lock).    *! -  *! @param recursive -  *! Support the same thread obtaining several locks -  *! (both read and write). -  *! +     *! @throws    *! Throws an error if the current thread already has -  *! a lock (read or write) unless @[recursive] is @expr{1@}. +  *! a lock (read or write).    *! -  *! If @[recursive] is @expr{1@} it will still throw an error -  *! if we have a read lock and another thread has started -  *! taking a write lock. -  *! +     *! @seealso    *! @[read_lock()]    */   static void f_rwmutex_write_lock(INT32 args)   {    ref_push_object_inherit(Pike_fp->current_object,    Pike_fp->context -    Pike_fp->current_object->prog->inherits);    push_object(clone_object(rwmutex_wkey_program, 1));   }
pike.git/src/threads.c:2819:    free_object(rwmutex_obj);    }    }   }      static void f_rwmutex_rkey_create(INT32 args)   {    struct object *rwmutex_obj = NULL;    struct rwmutex_storage *rwmutex = NULL;    struct rwmutex_key_storage *m; -  int recursive = 0; +     int self_count = 0;    -  get_all_args("create", args, "%o.%d", &rwmutex_obj, &recursive); +  get_all_args("create", args, "%o", &rwmutex_obj);    if (!(rwmutex = get_storage(rwmutex_obj, rwmutex_program))) {    SIMPLE_ARG_TYPE_ERROR("create", 1, "RWMutex");    }       while (THIS_RWKEY->rwmutex) {    /* Not really a supported operation, but... */    exit_rwmutex_rkey_obj(NULL);    }       for (m = rwmutex->first_key; m; m = m->next) {    if ((m->owner == Pike_interpreter.thread_state) && (m->owner)) {    self_count++;    }    }    -  if (self_count && recursive) { +  if (self_count) {    /* NB: We have a lock already.    *    * This is a bad idea, as it may lead to dead-locks    * if another thread has started an attempt to get    * a write lock between our two read locks, or if    * we already hold the write lock.    */    Pike_error("Recursive mutex locks!\n");    }   
pike.git/src/threads.c:2969:    free_object(rwmutex_obj);    }    }   }      static void f_rwmutex_wkey_create(INT32 args)   {    struct object *rwmutex_obj = NULL;    struct rwmutex_storage *rwmutex = NULL;    struct rwmutex_key_storage *m; -  int recursive = 0; +     int self_count = 0;    -  get_all_args("create", args, "%o.%d", &rwmutex_obj, &recursive); +  get_all_args("create", args, "%o", &rwmutex_obj);    if (!(rwmutex = get_storage(rwmutex_obj, rwmutex_program))) {    SIMPLE_ARG_TYPE_ERROR("create", 1, "RWMutex");    }       while (THIS_RWKEY->rwmutex) {    /* Not really a supported operation, but... */    exit_rwmutex_wkey_obj(NULL);    }       for (m = rwmutex->first_key; m; m = m->next) {    if (m->owner && (m->owner = Pike_interpreter.thread_state)) {    self_count++;    }    }    -  if (self_count && (!recursive || (rwmutex->writers < 0))) { +  if (self_count) {    /* Either: We already have a lock (read or write), and    * would hang waiting on ourselves. -  * -  * Or: We already have a lock and some other thread is -  * already attempting to get a write lock. This -  * would end up in a hang waiting on the other -  * thread while it is waiting on us. +     */    Pike_error("Recursive mutex locks!\n");    }       init_rwmutex_key_obj(NULL);       THIS_RWKEY->rwmutex = rwmutex;    THIS_RWKEY->rwmutex_obj = rwmutex_obj;    add_ref(rwmutex_obj);