Differences From Artifact [106c451b62]:
- File src/runtime/synchronized.m — part of check-in [8f271bed22] at 2020-12-20 03:06:55 on branch trunk — Let OF_ENSURE use OBJC_ERROR in runtime (user: js, size: 2778) [annotate] [blame] [check-ins using] [more...]
To Artifact [8b8ee09700]:
- File
src/runtime/synchronized.m
— part of check-in
[5b37fbeb82]
at
2020-12-20 21:26:08
on branch trunk
— Return error instead of using errno for threading
errno is problematic for Amiga libraries and is also not thread-safe on
some systems, even though it should. (user: js, size: 2822) [annotate] [blame] [check-ins using] [more...]
︙ | ︙ | |||
33 34 35 36 37 38 39 | struct lock_s *next; } *locks = NULL; static of_mutex_t mutex; OF_CONSTRUCTOR() { | | | | | | | | | | | | | 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | struct lock_s *next; } *locks = NULL; static of_mutex_t mutex; OF_CONSTRUCTOR() { if (of_mutex_new(&mutex) != 0) OBJC_ERROR("Failed to create mutex!"); } #endif int objc_sync_enter(id object) { if (object == nil) return 0; #ifdef OF_HAVE_THREADS struct lock_s *lock; if (of_mutex_lock(&mutex) != 0) OBJC_ERROR("Failed to lock mutex!"); /* Look if we already have a lock */ for (lock = locks; lock != NULL; lock = lock->next) { if (lock->object != object) continue; lock->count++; if (of_mutex_unlock(&mutex) != 0) OBJC_ERROR("Failed to unlock mutex!"); if (of_rmutex_lock(&lock->rmutex) != 0) OBJC_ERROR("Failed to lock mutex!"); return 0; } /* Create a new lock */ if ((lock = malloc(sizeof(*lock))) == NULL) OBJC_ERROR("Failed to allocate memory for mutex!"); if (of_rmutex_new(&lock->rmutex) != 0) OBJC_ERROR("Failed to create mutex!"); lock->object = object; lock->count = 1; lock->next = locks; locks = lock; if (of_mutex_unlock(&mutex) != 0) OBJC_ERROR("Failed to unlock mutex!"); if (of_rmutex_lock(&lock->rmutex) != 0) OBJC_ERROR("Failed to lock mutex!"); #endif return 0; } int objc_sync_exit(id object) { if (object == nil) return 0; #ifdef OF_HAVE_THREADS struct lock_s *lock, *last = NULL; if (of_mutex_lock(&mutex) != 0) OBJC_ERROR("Failed to lock mutex!"); for (lock = locks; lock != NULL; lock = lock->next) { if (lock->object != object) { last = lock; continue; } if (of_rmutex_unlock(&lock->rmutex) != 0) OBJC_ERROR("Failed to unlock mutex!"); if (--lock->count == 0) { if (of_rmutex_free(&lock->rmutex) != 0) OBJC_ERROR("Failed to destroy mutex!"); if (last != NULL) last->next = lock->next; if (locks == lock) locks = lock->next; free(lock); } if (of_mutex_unlock(&mutex) != 0) OBJC_ERROR("Failed to unlock mutex!"); return 0; } OBJC_ERROR("objc_sync_exit() was called for an object not locked!"); #else return 0; #endif } |