Index: src/objc_sync.m ================================================================== --- src/objc_sync.m +++ src/objc_sync.m @@ -11,10 +11,11 @@ #include "config.h" #include #include +#include #ifndef _WIN32 #include #endif @@ -140,17 +141,31 @@ for (i = 0; i < num_locks; i++) { if (locks[i].obj == obj) { if (thread_is_current(locks[i].thread)) locks[i].recursion++; - else + else { + /* Make sure objc_sync_exit doesn't free it */ + locks[i].count++; + + /* Unlock so objc_sync_exit can return */ + if (!mutex_unlock(&mutex)) + return 1; + if (!mutex_lock(&locks[i].mutex)) { mutex_unlock(&mutex); return 1; } - locks[i].count++; + if (!mutex_lock(&mutex)) + return 1; + + assert(locks[i].recursion == 0); + + /* Update lock's active thread */ + locks[i].thread = thread_current(); + } if (!mutex_unlock(&mutex)) return 1; return 0; @@ -226,22 +241,26 @@ } locks[i].count--; if (locks[i].count == 0) { - struct locks_s *new_locks; + struct locks_s *new_locks = NULL; if (!mutex_free(&locks[i].mutex)) { mutex_unlock(&mutex); return 1; } num_locks--; locks[i] = locks[num_locks]; - if ((new_locks = realloc(locks, (num_locks) * - sizeof(struct locks_s))) == NULL) { + if (num_locks == 0) { + free(locks); + new_locks = NULL; + } else if ((new_locks = realloc(locks, + num_locks * sizeof(struct locks_s))) == + NULL) { mutex_unlock(&mutex); return 1; } locks = new_locks;