Comment: | Move platform specific files into a subdirectory |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
109db78ecd3d8dfef159bdabd787a260 |
User & Date: | js on 2020-02-29 14:49:23 |
Other Links: | manifest | tags |
2020-02-29
| ||
16:09 | Move OFProcess to platform subdirectory check-in: 5ca0376aa3 user: js tags: trunk | |
14:49 | Move platform specific files into a subdirectory check-in: 109db78ecd user: js tags: trunk | |
2020-02-27
| ||
23:53 | ofhttp: Properly reset _length on redirect check-in: 283aece9e8 user: js tags: trunk | |
Modified src/OFString+PathAdditions.m from [5f71f32820] to [ea666f96ec].
︙ | ︙ | |||
13 14 15 16 17 18 19 | * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" | | | | | | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include "platform.h" #if defined(OF_WINDOWS) || defined(OF_MSDOS) # import "platform/windows/OFString+PathAdditions.m" #elif defined(OF_AMIGAOS) # import "platform/amiga/OFString+PathAdditions.m" #elif defined(OF_NINTENDO_3DS) || defined(OF_WII) # import "platform/libfat/OFString+PathAdditions.m" #else # import "platform/posix/OFString+PathAdditions.m" #endif |
Deleted src/OFString+PathAdditions_AmigaOS.m version [569b6c48d1].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFString+PathAdditions_DOS.m version [d2942a5799].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFString+PathAdditions_UNIX.m version [3ec0045bce].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFString+PathAdditions_libfat.m version [fc28106dee].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Modified src/condition.m from [4bb0d2c489] to [f3cd7e798e].
︙ | ︙ | |||
13 14 15 16 17 18 19 | * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" | | | | | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include "platform.h" #if defined(OF_HAVE_PTHREADS) # include "platform/posix/condition.m" #elif defined(OF_WINDOWS) # include "platform/windows/condition.m" #elif defined(OF_AMIGAOS) # include "platform/amiga/condition.m" #endif |
Deleted src/condition_amiga.m version [04fb252eb9].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/condition_pthread.m version [2114ae2a5d].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/condition_winapi.m version [77885a7360].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Modified src/mutex.m from [017d59173c] to [b45f1dde14].
︙ | ︙ | |||
13 14 15 16 17 18 19 | * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" | | | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include "platform.h" #if defined(OF_HAVE_PTHREADS) # include "platform/posix/mutex.m" #elif defined(OF_WINDOWS) # include "platform/windows/mutex.m" #elif defined(OF_AMIGAOS) # include "platform/amiga/mutex.m" #endif |
Deleted src/mutex_amiga.m version [85aa6b25fd].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/mutex_pthread.m version [17f029cc73].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/mutex_winapi.m version [7d6a62c858].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added src/platform/amiga/OFString+PathAdditions.m version [569b6c48d1].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 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 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFString+PathAdditions.h" #import "OFArray.h" #import "OFOutOfRangeException.h" int _OFString_PathAdditions_reference; @implementation OFString (PathAdditions) + (OFString *)pathWithComponents: (OFArray *)components { OFMutableString *ret = [OFMutableString string]; void *pool = objc_autoreleasePoolPush(); bool firstAfterDevice = true; for (OFString *component in components) { if (component.length == 0) continue; if (!firstAfterDevice) [ret appendString: @"/"]; [ret appendString: component]; if (![component hasSuffix: @":"]) firstAfterDevice = false; } [ret makeImmutable]; objc_autoreleasePoolPop(pool); return ret; } - (bool)isAbsolutePath { return [self containsString: @":"]; } - (OFArray *)pathComponents { OFMutableArray OF_GENERIC(OFString *) *ret = [OFMutableArray array]; void *pool = objc_autoreleasePoolPush(); const char *cString = self.UTF8String; size_t i, last = 0, cStringLength = self.UTF8StringLength; if (cStringLength == 0) { objc_autoreleasePoolPop(pool); return ret; } for (i = 0; i < cStringLength; i++) { if (cString[i] == '/') { if (i - last != 0) [ret addObject: [OFString stringWithUTF8String: cString + last length: i - last]]; else [ret addObject: @"/"]; last = i + 1; } else if (cString[i] == ':') { [ret addObject: [OFString stringWithUTF8String: cString + last length: i - last + 1]]; last = i + 1; } } if (i - last != 0) [ret addObject: [OFString stringWithUTF8String: cString + last length: i - last]]; [ret makeImmutable]; objc_autoreleasePoolPop(pool); return ret; } - (OFString *)lastPathComponent { /* * AmigaOS needs the full parsing to determine the last path component. * This could be optimized by not creating the temporary objects, * though. */ void *pool = objc_autoreleasePoolPush(); OFString *ret = self.pathComponents.lastObject; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFString *)pathExtension { void *pool = objc_autoreleasePoolPush(); OFString *ret, *fileName; size_t pos; fileName = self.lastPathComponent; pos = [fileName rangeOfString: @"." options: OF_STRING_SEARCH_BACKWARDS].location; if (pos == OF_NOT_FOUND || pos == 0) { objc_autoreleasePoolPop(pool); return @""; } ret = [fileName substringWithRange: of_range(pos + 1, fileName.length - pos - 1)]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFString *)stringByDeletingLastPathComponent { /* * AmigaOS needs the full parsing to delete the last path component. * This could be optimized, though. */ void *pool = objc_autoreleasePoolPush(); OFArray OF_GENERIC(OFString *) *components = self.pathComponents; size_t count = components.count; OFString *ret; if (count < 2) { if ([components.firstObject hasSuffix: @":"]) { ret = [components.firstObject retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } objc_autoreleasePoolPop(pool); return @""; } components = [components objectsInRange: of_range(0, components.count - 1)]; ret = [OFString pathWithComponents: components]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFString *)stringByDeletingPathExtension { void *pool; OFMutableArray OF_GENERIC(OFString *) *components; OFString *ret, *fileName; size_t pos; if (self.length == 0) return [[self copy] autorelease]; pool = objc_autoreleasePoolPush(); components = [[self.pathComponents mutableCopy] autorelease]; fileName = components.lastObject; pos = [fileName rangeOfString: @"." options: OF_STRING_SEARCH_BACKWARDS].location; if (pos == OF_NOT_FOUND || pos == 0) { objc_autoreleasePoolPop(pool); return [[self copy] autorelease]; } fileName = [fileName substringWithRange: of_range(0, pos)]; [components replaceObjectAtIndex: components.count - 1 withObject: fileName]; ret = [OFString pathWithComponents: components]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFString *)stringByStandardizingPath { void *pool = objc_autoreleasePoolPush(); OFArray OF_GENERIC(OFString *) *components; OFMutableArray OF_GENERIC(OFString *) *array; OFString *ret; bool done = false; if (self.length == 0) return @""; components = self.pathComponents; if (components.count == 1) { objc_autoreleasePoolPop(pool); return [[self copy] autorelease]; } array = [[components mutableCopy] autorelease]; while (!done) { size_t length = array.count; done = true; for (size_t i = 0; i < length; i++) { OFString *component = [array objectAtIndex: i]; OFString *parent = (i > 0 ? [array objectAtIndex: i - 1] : 0); if (component.length == 0) { [array removeObjectAtIndex: i]; done = false; break; } if ([component isEqual: @"/"] && parent != nil && ![parent isEqual: @"/"]) { [array removeObjectsInRange: of_range(i - 1, 2)]; done = false; break; } } } ret = [OFString pathWithComponents: array]; if ([self hasSuffix: @"/"]) ret = [ret stringByAppendingString: @"/"]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFString *)stringByAppendingPathComponent: (OFString *)component { if ([self hasSuffix: @"/"] || [self hasSuffix: @":"]) return [self stringByAppendingString: component]; else { OFMutableString *ret = [[self mutableCopy] autorelease]; [ret appendString: @"/"]; [ret appendString: component]; [ret makeImmutable]; return ret; } } @end |
Added src/platform/amiga/condition.m version [022f3487c0].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 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 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <errno.h> #import "condition.h" #include <proto/exec.h> #include <devices/timer.h> #ifndef OF_AMIGAOS4 # include <clib/alib_protos.h> #endif bool of_condition_new(of_condition_t *condition) { condition->waitingTasks = NULL; return true; } bool of_condition_signal(of_condition_t *condition) { Forbid(); @try { if (condition->waitingTasks == NULL) return true; Signal(condition->waitingTasks->task, (1ul << condition->waitingTasks->sigBit)); condition->waitingTasks = condition->waitingTasks->next; } @finally { Permit(); } return true; } bool of_condition_broadcast(of_condition_t *condition) { Forbid(); @try { if (condition->waitingTasks == NULL) return true; while (condition->waitingTasks != NULL) { Signal(condition->waitingTasks->task, (1ul << condition->waitingTasks->sigBit)); condition->waitingTasks = condition->waitingTasks->next; } } @finally { Permit(); } return true; } bool of_condition_wait(of_condition_t *condition, of_mutex_t *mutex) { ULONG signalMask = 0; return of_condition_wait_or_signal(condition, mutex, &signalMask); } bool of_condition_wait_or_signal(of_condition_t *condition, of_mutex_t *mutex, ULONG *signalMask) { struct of_condition_waiting_task waitingTask = { .task = FindTask(NULL), .sigBit = AllocSignal(-1) }; bool ret; ULONG mask; if (waitingTask.sigBit == -1) { errno = EAGAIN; return false; } Forbid(); if (!of_mutex_unlock(mutex)) { FreeSignal(waitingTask.sigBit); return false; } waitingTask.next = condition->waitingTasks; condition->waitingTasks = &waitingTask; mask = Wait((1ul << waitingTask.sigBit) | *signalMask); if (mask & (1ul << waitingTask.sigBit) || (*signalMask &= mask)) ret = of_mutex_lock(mutex); else { /* * This should not happen - it means something interrupted the * Wait(), so the best we can do is return EINTR. */ ret = false; errno = EINTR; } FreeSignal(waitingTask.sigBit); Permit(); return ret; } bool of_condition_timed_wait(of_condition_t *condition, of_mutex_t *mutex, of_time_interval_t timeout) { ULONG signalMask = 0; return of_condition_timed_wait_or_signal(condition, mutex, timeout, &signalMask); } bool of_condition_timed_wait_or_signal(of_condition_t *condition, of_mutex_t *mutex, of_time_interval_t timeout, ULONG *signalMask) { struct of_condition_waiting_task waitingTask = { .task = FindTask(NULL), .sigBit = AllocSignal(-1) }; struct MsgPort port = { .mp_Node = { .ln_Type = NT_MSGPORT }, .mp_Flags = PA_SIGNAL, .mp_SigTask = waitingTask.task, .mp_SigBit = AllocSignal(-1) }; #ifdef OF_AMIGAOS4 struct TimeRequest request = { .Request = { #else struct timerequest request = { .tr_node = { #endif .io_Message = { .mn_Node = { .ln_Type = NT_MESSAGE }, .mn_ReplyPort = &port, .mn_Length = sizeof(request) }, .io_Command = TR_ADDREQUEST }, #ifdef OF_AMIGAOS4 .Time = { .Seconds = (ULONG)timeout, .Microseconds = (timeout - request.Time.Seconds) * 1000000 #else .tr_time = { .tv_sec = (ULONG)timeout, .tv_micro = (timeout - request.tr_time.tv_sec) * 1000000 #endif } }; ULONG mask; bool ret; NewList(&port.mp_MsgList); if (waitingTask.sigBit == -1 || port.mp_SigBit == -1) { errno = EAGAIN; goto fail; } if (OpenDevice("timer.device", UNIT_MICROHZ, (struct IORequest *)&request, 0) != 0) { errno = EAGAIN; goto fail; } Forbid(); if (!of_mutex_unlock(mutex)) { Permit(); goto fail; } waitingTask.next = condition->waitingTasks; condition->waitingTasks = &waitingTask; SendIO((struct IORequest *)&request); mask = Wait((1ul << waitingTask.sigBit) | (1ul << port.mp_SigBit) | *signalMask); if (mask & (1ul << waitingTask.sigBit) || (*signalMask &= mask)) ret = of_mutex_lock(mutex); else if (mask & (1ul << port.mp_SigBit)) { ret = false; errno = ETIMEDOUT; } else { /* * This should not happen - it means something interrupted the * Wait(), so the best we can do is return EINTR. */ ret = false; errno = EINTR; } condition->waitingTasks = waitingTask.next; if (!CheckIO((struct IORequest *)&request)) { AbortIO((struct IORequest *)&request); WaitIO((struct IORequest *)&request); } CloseDevice((struct IORequest *)&request); Permit(); FreeSignal(waitingTask.sigBit); FreeSignal(port.mp_SigBit); return ret; fail: if (waitingTask.sigBit != -1) FreeSignal(waitingTask.sigBit); if (port.mp_SigBit != -1) FreeSignal(port.mp_SigBit); return false; } bool of_condition_free(of_condition_t *condition) { Forbid(); @try { if (condition->waitingTasks != NULL) { errno = EBUSY; return false; } } @finally { Permit(); } return true; } |
Added src/platform/amiga/mutex.m version [c8d24f47bf].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 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 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <errno.h> #import "mutex.h" #include <proto/exec.h> bool of_mutex_new(of_mutex_t *mutex) { InitSemaphore(mutex); return true; } bool of_mutex_lock(of_mutex_t *mutex) { ObtainSemaphore(mutex); return true; } bool of_mutex_trylock(of_mutex_t *mutex) { if (!AttemptSemaphore(mutex)) { errno = EBUSY; return false; } return true; } bool of_mutex_unlock(of_mutex_t *mutex) { ReleaseSemaphore(mutex); return true; } bool of_mutex_free(of_mutex_t *mutex) { return true; } bool of_rmutex_new(of_rmutex_t *rmutex) { return of_mutex_new(rmutex); } bool of_rmutex_lock(of_rmutex_t *rmutex) { return of_mutex_lock(rmutex); } bool of_rmutex_trylock(of_rmutex_t *rmutex) { return of_mutex_trylock(rmutex); } bool of_rmutex_unlock(of_rmutex_t *rmutex) { return of_mutex_unlock(rmutex); } bool of_rmutex_free(of_rmutex_t *rmutex) { return of_mutex_free(rmutex); } |
Added src/platform/amiga/thread.m version [7b264a994b].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 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 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <assert.h> #include <errno.h> #import "OFData.h" #import "thread.h" #import "tlskey.h" #include <dos/dostags.h> #include <proto/dos.h> #include <proto/exec.h> extern void of_tlskey_thread_exited(void); static of_tlskey_t threadKey; OF_CONSTRUCTOR() { OF_ENSURE(of_tlskey_new(&threadKey)); } static void functionWrapper(void) { bool detached = false; of_thread_t thread = (of_thread_t)((struct Process *)FindTask(NULL))->pr_ExitData; OF_ENSURE(of_tlskey_set(threadKey, thread)); thread->function(thread->object); ObtainSemaphore(&thread->semaphore); @try { thread->done = true; of_tlskey_thread_exited(); if (thread->detached) detached = true; else if (thread->joinTask != NULL) Signal(thread->joinTask, (1ul << thread->joinSigBit)); } @finally { ReleaseSemaphore(&thread->semaphore); } if (detached) free(thread); } bool of_thread_attr_init(of_thread_attr_t *attr) { attr->priority = 0; attr->stackSize = 0; return true; } bool of_thread_new(of_thread_t *thread, const char *name, void (*function)(id), id object, const of_thread_attr_t *attr) { OFMutableData *tags = nil; if ((*thread = calloc(1, sizeof(**thread))) == NULL) { errno = ENOMEM; return false; } @try { (*thread)->function = function; (*thread)->object = object; InitSemaphore(&(*thread)->semaphore); tags = [[OFMutableData alloc] initWithItemSize: sizeof(struct TagItem) capacity: 12]; #define ADD_TAG(tag, data) \ { \ struct TagItem t = { \ .ti_Tag = tag, \ .ti_Data = data \ }; \ [tags addItem: &t]; \ } ADD_TAG(NP_Entry, (ULONG)functionWrapper) ADD_TAG(NP_ExitData, (ULONG)*thread) #ifdef OF_AMIGAOS4 ADD_TAG(NP_Child, TRUE) #endif #ifdef OF_MORPHOS ADD_TAG(NP_CodeType, CODETYPE_PPC); #endif if (name != NULL) ADD_TAG(NP_Name, (ULONG)name); ADD_TAG(NP_Input, ((struct Process *)FindTask(NULL))->pr_CIS) ADD_TAG(NP_Output, ((struct Process *)FindTask(NULL))->pr_COS) ADD_TAG(NP_Error, ((struct Process *)FindTask(NULL))->pr_CES) ADD_TAG(NP_CloseInput, FALSE) ADD_TAG(NP_CloseOutput, FALSE) ADD_TAG(NP_CloseError, FALSE) if (attr != NULL && attr->priority != 0) { if (attr->priority < 1 || attr->priority > 1) { errno = EINVAL; return false; } /* * -1 should be -128 (lowest possible priority) while * +1 should be +127 (highest possible priority). */ ADD_TAG(NP_Priority, (attr->priority > 0 ? attr->priority * 127 : attr->priority * 128)) } if (attr != NULL && attr->stackSize != 0) ADD_TAG(NP_StackSize, attr->stackSize) else ADD_TAG(NP_StackSize, ((struct Process *)FindTask(NULL))->pr_StackSize) ADD_TAG(TAG_DONE, 0) #undef ADD_TAG (*thread)->task = (struct Task *)CreateNewProc(tags.items); if ((*thread)->task == NULL) { free(*thread); errno = EAGAIN; return false; } } @catch (id e) { free(*thread); @throw e; } @finally { [tags release]; } return true; } of_thread_t of_thread_current(void) { return of_tlskey_get(threadKey); } bool of_thread_join(of_thread_t thread) { ObtainSemaphore(&thread->semaphore); @try { if (thread->done) { free(thread); return true; } if (thread->detached || thread->joinTask != NULL) { errno = EINVAL; return false; } if ((thread->joinSigBit = AllocSignal(-1)) == -1) { errno = EAGAIN; return false; } thread->joinTask = FindTask(NULL); } @finally { ReleaseSemaphore(&thread->semaphore); } Wait(1ul << thread->joinSigBit); FreeSignal(thread->joinSigBit); assert(thread->done); free(thread); return true; } bool of_thread_detach(of_thread_t thread) { ObtainSemaphore(&thread->semaphore); if (thread->done) free(thread); else thread->detached = true; ReleaseSemaphore(&thread->semaphore); return true; } void of_thread_set_name(const char *name) { } |
Added src/platform/amiga/tlskey.m version [c1bdeb2ced].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 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 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "tlskey.h" #include <exec/semaphores.h> #include <proto/exec.h> /* * As we use this file in both the runtime and ObjFW, and since AmigaOS always * has the runtime, use the hashtable from the runtime. */ #import "runtime/private.h" static of_tlskey_t firstKey = NULL, lastKey = NULL; static struct SignalSemaphore semaphore; static bool semaphoreInitialized = false; static uint32_t hashFunc(const void *ptr) { return (uint32_t)(uintptr_t)ptr; } static bool equalFunc(const void *ptr1, const void *ptr2) { return (ptr1 == ptr2); } OF_CONSTRUCTOR() { if (!semaphoreInitialized) { InitSemaphore(&semaphore); semaphoreInitialized = true; } } bool of_tlskey_new(of_tlskey_t *key) { if (!semaphoreInitialized) { /* * We might be called from another constructor, while ours has * not run yet. This is safe, as the constructor is definitely * run before a thread is spawned. */ InitSemaphore(&semaphore); semaphoreInitialized = true; } if ((*key = malloc(sizeof(**key))) == NULL) return false; (*key)->table = NULL; ObtainSemaphore(&semaphore); @try { (*key)->next = NULL; (*key)->previous = lastKey; if (lastKey != NULL) lastKey->next = *key; lastKey = *key; if (firstKey == NULL) firstKey = *key; } @finally { ReleaseSemaphore(&semaphore); } /* We create the hash table lazily. */ return true; } bool of_tlskey_free(of_tlskey_t key) { ObtainSemaphore(&semaphore); @try { if (key->previous != NULL) key->previous->next = key->next; if (key->next != NULL) key->next->previous = key->previous; if (firstKey == key) firstKey = key->next; if (lastKey == key) lastKey = key->previous; objc_hashtable_free(key->table); free(key); } @finally { ReleaseSemaphore(&semaphore); } return true; } void * of_tlskey_get(of_tlskey_t key) { void *ret; ObtainSemaphore(&semaphore); @try { if (key->table == NULL) return NULL; ret = objc_hashtable_get(key->table, FindTask(NULL)); } @finally { ReleaseSemaphore(&semaphore); } return ret; } bool of_tlskey_set(of_tlskey_t key, void *ptr) { ObtainSemaphore(&semaphore); @try { struct Task *task = FindTask(NULL); if (key->table == NULL) key->table = objc_hashtable_new(hashFunc, equalFunc, 2); if (ptr == NULL) objc_hashtable_delete(key->table, task); else objc_hashtable_set(key->table, task, ptr); } @catch (id e) { return false; } @finally { ReleaseSemaphore(&semaphore); } return true; } void of_tlskey_thread_exited(void) { ObtainSemaphore(&semaphore); @try { struct Task *task = FindTask(NULL); for (of_tlskey_t iter = firstKey; iter != NULL; iter = iter->next) if (iter->table != NULL) objc_hashtable_delete(iter->table, task); } @finally { ReleaseSemaphore(&semaphore); } } |
Added src/platform/libfat/OFString+PathAdditions.m version [fc28106dee].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 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 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFString+PathAdditions.h" #import "OFArray.h" #import "OFOutOfRangeException.h" int _OFString_PathAdditions_reference; @implementation OFString (PathAdditions) + (OFString *)pathWithComponents: (OFArray *)components { OFMutableString *ret = [OFMutableString string]; void *pool = objc_autoreleasePoolPush(); bool first = true; for (OFString *component in components) { if (component.length == 0) continue; if ([component isEqual: @"/"]) continue; if (!first && ![ret hasSuffix: @"/"]) [ret appendString: @"/"]; [ret appendString: component]; first = false; } if ([ret hasSuffix: @":"]) [ret appendString: @"/"]; [ret makeImmutable]; objc_autoreleasePoolPop(pool); return ret; } - (bool)isAbsolutePath { return [self containsString: @":/"]; } - (OFArray *)pathComponents { OFMutableArray OF_GENERIC(OFString *) *ret = [OFMutableArray array]; void *pool = objc_autoreleasePoolPush(); const char *cString = self.UTF8String; size_t i, last = 0, cStringLength = self.UTF8StringLength; if (cStringLength == 0) { objc_autoreleasePoolPop(pool); return ret; } for (i = 0; i < cStringLength; i++) { if (cString[i] == '/') { if (i - last != 0) [ret addObject: [OFString stringWithUTF8String: cString + last length: i - last]]; last = i + 1; } } if (i - last != 0) [ret addObject: [OFString stringWithUTF8String: cString + last length: i - last]]; [ret makeImmutable]; objc_autoreleasePoolPop(pool); return ret; } - (OFString *)lastPathComponent { void *pool = objc_autoreleasePoolPush(); const char *cString; size_t cStringLength; ssize_t i; OFString *ret; if ([self hasSuffix: @":/"]) return self; cString = self.UTF8String; cStringLength = self.UTF8StringLength; if (cStringLength == 0) { objc_autoreleasePoolPop(pool); return @""; } if (cString[cStringLength - 1] == '/') cStringLength--; if (cStringLength == 0) { objc_autoreleasePoolPop(pool); return @""; } if (cStringLength - 1 > SSIZE_MAX) @throw [OFOutOfRangeException exception]; for (i = cStringLength - 1; i >= 0; i--) { if (cString[i] == '/') { i++; break; } } /* * Only one component, but the trailing delimiter might have been * removed, so return a new string anyway. */ if (i < 0) i = 0; ret = [[OFString alloc] initWithUTF8String: cString + i length: cStringLength - i]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFString *)pathExtension { void *pool = objc_autoreleasePoolPush(); OFString *ret, *fileName; size_t pos; fileName = self.lastPathComponent; pos = [fileName rangeOfString: @"." options: OF_STRING_SEARCH_BACKWARDS].location; if (pos == OF_NOT_FOUND || pos == 0) { objc_autoreleasePoolPop(pool); return @""; } ret = [fileName substringWithRange: of_range(pos + 1, fileName.length - pos - 1)]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFString *)stringByDeletingLastPathComponent { void *pool = objc_autoreleasePoolPush(); const char *cString; size_t cStringLength; OFString *ret; if ([self hasSuffix: @":/"]) return self; cString = self.UTF8String; cStringLength = self.UTF8StringLength; if (cStringLength == 0) { objc_autoreleasePoolPop(pool); return @""; } if (cString[cStringLength - 1] == '/') cStringLength--; if (cStringLength == 0) { objc_autoreleasePoolPop(pool); return @""; } for (size_t i = cStringLength; i >= 1; i--) { if (cString[i - 1] == '/') { ret = [[OFString alloc] initWithUTF8String: cString length: i - 1]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } } objc_autoreleasePoolPop(pool); return @"."; } - (OFString *)stringByDeletingPathExtension { void *pool; OFMutableArray OF_GENERIC(OFString *) *components; OFString *ret, *fileName; size_t pos; if (self.length == 0) return [[self copy] autorelease]; pool = objc_autoreleasePoolPush(); components = [[self.pathComponents mutableCopy] autorelease]; fileName = components.lastObject; pos = [fileName rangeOfString: @"." options: OF_STRING_SEARCH_BACKWARDS].location; if (pos == OF_NOT_FOUND || pos == 0) { objc_autoreleasePoolPop(pool); return [[self copy] autorelease]; } fileName = [fileName substringWithRange: of_range(0, pos)]; [components replaceObjectAtIndex: components.count - 1 withObject: fileName]; ret = [OFString pathWithComponents: components]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFString *)stringByStandardizingPath { void *pool = objc_autoreleasePoolPush(); OFArray OF_GENERIC(OFString *) *components; OFMutableArray OF_GENERIC(OFString *) *array; OFString *ret; bool done = false; if (self.length == 0) return @""; components = self.pathComponents; if (components.count == 1) { objc_autoreleasePoolPop(pool); return [[self copy] autorelease]; } array = [[components mutableCopy] autorelease]; while (!done) { size_t length = array.count; done = true; for (size_t i = 0; i < length; i++) { OFString *component = [array objectAtIndex: i]; OFString *parent = (i > 0 ? [array objectAtIndex: i - 1] : 0); if ([component isEqual: @"."] || component.length == 0) { [array removeObjectAtIndex: i]; done = false; break; } if ([component isEqual: @".."] && parent != nil && ![parent isEqual: @".."]) { [array removeObjectsInRange: of_range(i - 1, 2)]; done = false; break; } } } if ([self hasSuffix: @"/"]) [array addObject: @""]; ret = [[array componentsJoinedByString: @"/"] retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFString *)stringByAppendingPathComponent: (OFString *)component { if ([self hasSuffix: @"/"]) return [self stringByAppendingString: component]; else { OFMutableString *ret = [[self mutableCopy] autorelease]; [ret appendString: @"/"]; [ret appendString: component]; [ret makeImmutable]; return ret; } } @end |
Added src/platform/posix/OFString+PathAdditions.m version [3ec0045bce].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 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 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFString+PathAdditions.h" #import "OFArray.h" #import "OFOutOfRangeException.h" int _OFString_PathAdditions_reference; @implementation OFString (PathAdditions) + (OFString *)pathWithComponents: (OFArray *)components { OFMutableString *ret = [OFMutableString string]; void *pool = objc_autoreleasePoolPush(); bool first = true; for (OFString *component in components) { if (component.length == 0) continue; if (!first && [component isEqual: @"/"]) continue; if (!first && ![ret hasSuffix: @"/"]) [ret appendString: @"/"]; [ret appendString: component]; first = false; } [ret makeImmutable]; objc_autoreleasePoolPop(pool); return ret; } - (bool)isAbsolutePath { return [self hasPrefix: @"/"]; } - (OFArray *)pathComponents { OFMutableArray OF_GENERIC(OFString *) *ret = [OFMutableArray array]; void *pool = objc_autoreleasePoolPush(); const char *cString = self.UTF8String; size_t i, last = 0, cStringLength = self.UTF8StringLength; if (cStringLength == 0) { objc_autoreleasePoolPop(pool); return ret; } for (i = 0; i < cStringLength; i++) { if (cString[i] == '/') { if (i == 0) [ret addObject: @"/"]; else if (i - last != 0) [ret addObject: [OFString stringWithUTF8String: cString + last length: i - last]]; last = i + 1; } } if (i - last != 0) [ret addObject: [OFString stringWithUTF8String: cString + last length: i - last]]; [ret makeImmutable]; objc_autoreleasePoolPop(pool); return ret; } - (OFString *)lastPathComponent { void *pool = objc_autoreleasePoolPush(); const char *cString = self.UTF8String; size_t cStringLength = self.UTF8StringLength; ssize_t i; OFString *ret; if (cStringLength == 0) { objc_autoreleasePoolPop(pool); return @""; } if (cString[cStringLength - 1] == '/') cStringLength--; if (cStringLength == 0) { objc_autoreleasePoolPop(pool); return @"/"; } if (cStringLength - 1 > SSIZE_MAX) @throw [OFOutOfRangeException exception]; for (i = cStringLength - 1; i >= 0; i--) { if (cString[i] == '/') { i++; break; } } /* * Only one component, but the trailing delimiter might have been * removed, so return a new string anyway. */ if (i < 0) i = 0; ret = [[OFString alloc] initWithUTF8String: cString + i length: cStringLength - i]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFString *)pathExtension { void *pool = objc_autoreleasePoolPush(); OFString *ret, *fileName; size_t pos; fileName = self.lastPathComponent; pos = [fileName rangeOfString: @"." options: OF_STRING_SEARCH_BACKWARDS].location; if (pos == OF_NOT_FOUND || pos == 0) { objc_autoreleasePoolPop(pool); return @""; } ret = [fileName substringWithRange: of_range(pos + 1, fileName.length - pos - 1)]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFString *)stringByDeletingLastPathComponent { void *pool = objc_autoreleasePoolPush(); const char *cString = self.UTF8String; size_t cStringLength = self.UTF8StringLength; OFString *ret; if (cStringLength == 0) { objc_autoreleasePoolPop(pool); return @""; } if (cString[cStringLength - 1] == '/') cStringLength--; if (cStringLength == 0) { objc_autoreleasePoolPop(pool); return @"/"; } for (size_t i = cStringLength; i >= 1; i--) { if (cString[i - 1] == '/') { if (i == 1) { objc_autoreleasePoolPop(pool); return @"/"; } ret = [[OFString alloc] initWithUTF8String: cString length: i - 1]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } } objc_autoreleasePoolPop(pool); return @"."; } - (OFString *)stringByDeletingPathExtension { void *pool; OFMutableArray OF_GENERIC(OFString *) *components; OFString *ret, *fileName; size_t pos; if (self.length == 0) return [[self copy] autorelease]; pool = objc_autoreleasePoolPush(); components = [[self.pathComponents mutableCopy] autorelease]; fileName = components.lastObject; pos = [fileName rangeOfString: @"." options: OF_STRING_SEARCH_BACKWARDS].location; if (pos == OF_NOT_FOUND || pos == 0) { objc_autoreleasePoolPop(pool); return [[self copy] autorelease]; } fileName = [fileName substringWithRange: of_range(0, pos)]; [components replaceObjectAtIndex: [components count] - 1 withObject: fileName]; ret = [OFString pathWithComponents: components]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFString *)stringByStandardizingPath { void *pool = objc_autoreleasePoolPush(); OFArray OF_GENERIC(OFString *) *components; OFMutableArray OF_GENERIC(OFString *) *array; OFString *ret; bool done = false, startsWithSlash; if (self.length == 0) return @""; components = self.pathComponents; if (components.count == 1) { objc_autoreleasePoolPop(pool); return [[self copy] autorelease]; } array = [[components mutableCopy] autorelease]; startsWithSlash = [self hasPrefix: @"/"]; if (startsWithSlash) [array removeObjectAtIndex: 0]; while (!done) { size_t length = array.count; done = true; for (size_t i = 0; i < length; i++) { OFString *component = [array objectAtIndex: i]; OFString *parent = (i > 0 ? [array objectAtIndex: i - 1] : 0); if ([component isEqual: @"."] || component.length == 0) { [array removeObjectAtIndex: i]; done = false; break; } if ([component isEqual: @".."] && parent != nil && ![parent isEqual: @".."]) { [array removeObjectsInRange: of_range(i - 1, 2)]; done = false; break; } } } if (startsWithSlash) [array insertObject: @"" atIndex: 0]; if ([self hasSuffix: @"/"]) [array addObject: @""]; ret = [[array componentsJoinedByString: @"/"] retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFString *)stringByAppendingPathComponent: (OFString *)component { if ([self hasSuffix: @"/"]) return [self stringByAppendingString: component]; else { OFMutableString *ret = [[self mutableCopy] autorelease]; [ret appendString: @"/"]; [ret appendString: component]; [ret makeImmutable]; return ret; } } @end |
Added src/platform/posix/condition.m version [3ba4daa8bb].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 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 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "condition.h" bool of_condition_new(of_condition_t *condition) { return (pthread_cond_init(condition, NULL) == 0); } bool of_condition_signal(of_condition_t *condition) { return (pthread_cond_signal(condition) == 0); } bool of_condition_broadcast(of_condition_t *condition) { return (pthread_cond_broadcast(condition) == 0); } bool of_condition_wait(of_condition_t *condition, of_mutex_t *mutex) { return (pthread_cond_wait(condition, mutex) == 0); } bool of_condition_timed_wait(of_condition_t *condition, of_mutex_t *mutex, of_time_interval_t timeout) { struct timespec ts; ts.tv_sec = (time_t)timeout; ts.tv_nsec = (timeout - ts.tv_sec) * 1000000000; return (pthread_cond_timedwait(condition, mutex, &ts) == 0); } bool of_condition_free(of_condition_t *condition) { return (pthread_cond_destroy(condition) == 0); } |
Added src/platform/posix/mutex.m version [608d6df3a8].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 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 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "mutex.h" bool of_mutex_new(of_mutex_t *mutex) { return (pthread_mutex_init(mutex, NULL) == 0); } bool of_mutex_lock(of_mutex_t *mutex) { return (pthread_mutex_lock(mutex) == 0); } bool of_mutex_trylock(of_mutex_t *mutex) { return (pthread_mutex_trylock(mutex) == 0); } bool of_mutex_unlock(of_mutex_t *mutex) { return (pthread_mutex_unlock(mutex) == 0); } bool of_mutex_free(of_mutex_t *mutex) { return (pthread_mutex_destroy(mutex) == 0); } #ifdef OF_HAVE_RECURSIVE_PTHREAD_MUTEXES bool of_rmutex_new(of_rmutex_t *rmutex) { pthread_mutexattr_t attr; if (pthread_mutexattr_init(&attr) != 0) return false; if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) != 0) return false; if (pthread_mutex_init(rmutex, &attr) != 0) return false; if (pthread_mutexattr_destroy(&attr) != 0) return false; return true; } bool of_rmutex_lock(of_rmutex_t *rmutex) { return of_mutex_lock(rmutex); } bool of_rmutex_trylock(of_rmutex_t *rmutex) { return of_mutex_trylock(rmutex); } bool of_rmutex_unlock(of_rmutex_t *rmutex) { return of_mutex_unlock(rmutex); } bool of_rmutex_free(of_rmutex_t *rmutex) { return of_mutex_free(rmutex); } #else bool of_rmutex_new(of_rmutex_t *rmutex) { if (!of_mutex_new(&rmutex->mutex)) return false; if (!of_tlskey_new(&rmutex->count)) return false; return true; } bool of_rmutex_lock(of_rmutex_t *rmutex) { uintptr_t count = (uintptr_t)of_tlskey_get(rmutex->count); if (count > 0) { if (!of_tlskey_set(rmutex->count, (void *)(count + 1))) return false; return true; } if (!of_mutex_lock(&rmutex->mutex)) return false; if (!of_tlskey_set(rmutex->count, (void *)1)) { of_mutex_unlock(&rmutex->mutex); return false; } return true; } bool of_rmutex_trylock(of_rmutex_t *rmutex) { uintptr_t count = (uintptr_t)of_tlskey_get(rmutex->count); if (count > 0) { if (!of_tlskey_set(rmutex->count, (void *)(count + 1))) return false; return true; } if (!of_mutex_trylock(&rmutex->mutex)) return false; if (!of_tlskey_set(rmutex->count, (void *)1)) { of_mutex_unlock(&rmutex->mutex); return false; } return true; } bool of_rmutex_unlock(of_rmutex_t *rmutex) { uintptr_t count = (uintptr_t)of_tlskey_get(rmutex->count); if (count > 1) { if (!of_tlskey_set(rmutex->count, (void *)(count - 1))) return false; return true; } if (!of_tlskey_set(rmutex->count, (void *)0)) return false; if (!of_mutex_unlock(&rmutex->mutex)) return false; return true; } bool of_rmutex_free(of_rmutex_t *rmutex) { if (!of_mutex_free(&rmutex->mutex)) return false; if (!of_tlskey_free(rmutex->count)) return false; return true; } #endif |
Added src/platform/posix/thread.m version [537e06aaee].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 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 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <errno.h> #ifdef HAVE_PTHREAD_NP_H # include <pthread_np.h> #endif #ifdef OF_HAIKU # include <kernel/OS.h> #endif #import "thread.h" #import "macros.h" static int minPrio = 0, maxPrio = 0, normalPrio = 0; struct thread_ctx { void (*function)(id object); id object; const char *name; }; /* * This is done here to make sure this is done as early as possible in the main * thread. */ OF_CONSTRUCTOR() { pthread_attr_t pattr; if (pthread_attr_init(&pattr) == 0) { #ifdef HAVE_PTHREAD_ATTR_GETSCHEDPOLICY int policy; #endif struct sched_param param; #ifdef HAVE_PTHREAD_ATTR_GETSCHEDPOLICY if (pthread_attr_getschedpolicy(&pattr, &policy) == 0) { minPrio = sched_get_priority_min(policy); maxPrio = sched_get_priority_max(policy); if (minPrio == -1 || maxPrio == -1) minPrio = maxPrio = 0; } if (pthread_attr_getschedparam(&pattr, ¶m) != 0) normalPrio = param.sched_priority; else minPrio = maxPrio = 0; pthread_attr_destroy(&pattr); #endif } } static void * functionWrapper(void *data) { struct thread_ctx *ctx = data; if (ctx->name != NULL) of_thread_set_name(ctx->name); pthread_cleanup_push(free, data); ctx->function(ctx->object); pthread_cleanup_pop(1); return NULL; } bool of_thread_attr_init(of_thread_attr_t *attr) { pthread_attr_t pattr; if (pthread_attr_init(&pattr) != 0) return false; @try { attr->priority = 0; if (pthread_attr_getstacksize(&pattr, &attr->stackSize) != 0) return false; } @finally { pthread_attr_destroy(&pattr); } return true; } bool of_thread_new(of_thread_t *thread, const char *name, void (*function)(id), id object, const of_thread_attr_t *attr) { bool ret; pthread_attr_t pattr; if (pthread_attr_init(&pattr) != 0) return false; @try { struct thread_ctx *ctx; if (attr != NULL) { struct sched_param param; if (attr->priority < -1 || attr->priority > 1) { errno = EINVAL; return false; } #ifdef HAVE_PTHREAD_ATTR_SETINHERITSCHED if (pthread_attr_setinheritsched(&pattr, PTHREAD_EXPLICIT_SCHED) != 0) return false; #endif if (attr->priority < 0) { param.sched_priority = minPrio + (1.0f + attr->priority) * (normalPrio - minPrio); } else param.sched_priority = normalPrio + attr->priority * (maxPrio - normalPrio); if (pthread_attr_setschedparam(&pattr, ¶m) != 0) return false; if (attr->stackSize > 0) { if (pthread_attr_setstacksize(&pattr, attr->stackSize) != 0) return false; } } if ((ctx = malloc(sizeof(*ctx))) == NULL) { errno = ENOMEM; return false; } ctx->function = function; ctx->object = object; ctx->name = name; ret = (pthread_create(thread, &pattr, functionWrapper, ctx) == 0); } @finally { pthread_attr_destroy(&pattr); } return ret; } bool of_thread_join(of_thread_t thread) { void *ret; return (pthread_join(thread, &ret) == 0); } bool of_thread_detach(of_thread_t thread) { return (pthread_detach(thread) == 0); } void of_thread_set_name(const char *name) { #if defined(OF_HAIKU) rename_thread(find_thread(NULL), name); #elif defined(HAVE_PTHREAD_SET_NAME_NP) pthread_set_name_np(pthread_self(), name); #elif defined(HAVE_PTHREAD_SETNAME_NP) # if defined(OF_MACOS) || defined(OF_IOS) pthread_setname_np(name); # elif defined(__GLIBC__) char buffer[16]; strncpy(buffer, name, 15); buffer[15] = 0; pthread_setname_np(pthread_self(), buffer); # endif #endif } |
Added src/platform/posix/tlskey.m version [01a5f7adde].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "tlskey.h" bool of_tlskey_new(of_tlskey_t *key) { return (pthread_key_create(key, NULL) == 0); } bool of_tlskey_free(of_tlskey_t key) { return (pthread_key_delete(key) == 0); } |
Added src/platform/windows/OFString+PathAdditions.m version [c04745b26d].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 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 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ /* * This file is also used for MS-DOS! Don't forget to #ifdef Windows-specific * parts! */ #include "config.h" #import "OFString+PathAdditions.h" #import "OFArray.h" #import "OFOutOfRangeException.h" int _OFString_PathAdditions_reference; @implementation OFString (PathAdditions) + (OFString *)pathWithComponents: (OFArray *)components { OFMutableString *ret = [OFMutableString string]; void *pool = objc_autoreleasePoolPush(); bool first = true; for (OFString *component in components) { if (component.length == 0) continue; if (!first && ![ret hasSuffix: @":"] && ([component isEqual: @"\\"] || [component isEqual: @"/"])) continue; if (!first && ![ret hasSuffix: @"\\"] && ![ret hasSuffix: @"/"] && ![ret hasSuffix: @":"]) [ret appendString: @"\\"]; [ret appendString: component]; first = false; } [ret makeImmutable]; objc_autoreleasePoolPop(pool); return ret; } - (bool)isAbsolutePath { #ifdef OF_WINDOWS if ([self hasPrefix: @"\\\\"]) return true; #endif return ([self containsString: @":\\"] || [self containsString: @":/"]); } - (OFArray *)pathComponents { OFMutableArray OF_GENERIC(OFString *) *ret = [OFMutableArray array]; void *pool = objc_autoreleasePoolPush(); const char *cString = self.UTF8String; size_t i, last = 0, cStringLength = self.UTF8StringLength; bool isUNC = false; if (cStringLength == 0) { objc_autoreleasePoolPop(pool); return ret; } #ifdef OF_WINDOWS if ([self hasPrefix: @"\\\\"]) { isUNC = true; [ret addObject: @"\\\\"]; cString += 2; cStringLength -= 2; } #endif for (i = 0; i < cStringLength; i++) { if (cString[i] == '\\' || cString[i] == '/') { if (i == 0) [ret addObject: [OFString stringWithUTF8String: cString length: 1]]; else if (i - last != 0) [ret addObject: [OFString stringWithUTF8String: cString + last length: i - last]]; last = i + 1; } else if (!isUNC && cString[i] == ':') { if (i + 1 < cStringLength && (cString[i + 1] == '\\' || cString[i + 1] == '/')) i++; [ret addObject: [OFString stringWithUTF8String: cString + last length: i - last + 1]]; last = i + 1; } } if (i - last != 0) [ret addObject: [OFString stringWithUTF8String: cString + last length: i - last]]; [ret makeImmutable]; objc_autoreleasePoolPop(pool); return ret; } - (OFString *)lastPathComponent { /* * Windows/DOS need the full parsing to determine the last path * component. This could be optimized by not creating the temporary * objects, though. */ void *pool = objc_autoreleasePoolPush(); OFString *ret = self.pathComponents.lastObject; if (ret == nil) { objc_autoreleasePoolPop(pool); return @""; } [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFString *)pathExtension { void *pool = objc_autoreleasePoolPush(); OFString *ret, *fileName; size_t pos; fileName = self.lastPathComponent; pos = [fileName rangeOfString: @"." options: OF_STRING_SEARCH_BACKWARDS].location; if (pos == OF_NOT_FOUND || pos == 0) { objc_autoreleasePoolPop(pool); return @""; } ret = [fileName substringWithRange: of_range(pos + 1, fileName.length - pos - 1)]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFString *)stringByDeletingLastPathComponent { /* * Windows/DOS need the full parsing to delete the last path component. * This could be optimized, though. */ void *pool = objc_autoreleasePoolPush(); OFArray OF_GENERIC(OFString *) *components = self.pathComponents; size_t count = components.count; OFString *ret; if (count == 0) { objc_autoreleasePoolPop(pool); return @""; } if (count == 1) { OFString *firstComponent = components.firstObject; if ([firstComponent hasSuffix: @":"] || [firstComponent hasSuffix: @":\\"] || [firstComponent hasSuffix: @":/"] || [firstComponent hasPrefix: @"\\"]) { ret = [firstComponent retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } objc_autoreleasePoolPop(pool); return @"."; } components = [components objectsInRange: of_range(0, components.count - 1)]; ret = [OFString pathWithComponents: components]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFString *)stringByDeletingPathExtension { void *pool; OFMutableArray OF_GENERIC(OFString *) *components; OFString *ret, *fileName; size_t pos; if (self.length == 0) return [[self copy] autorelease]; pool = objc_autoreleasePoolPush(); components = [[self.pathComponents mutableCopy] autorelease]; fileName = components.lastObject; pos = [fileName rangeOfString: @"." options: OF_STRING_SEARCH_BACKWARDS].location; if (pos == OF_NOT_FOUND || pos == 0) { objc_autoreleasePoolPop(pool); return [[self copy] autorelease]; } fileName = [fileName substringWithRange: of_range(0, pos)]; [components replaceObjectAtIndex: components.count - 1 withObject: fileName]; ret = [OFString pathWithComponents: components]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFString *)stringByStandardizingPath { void *pool = objc_autoreleasePoolPush(); OFArray OF_GENERIC(OFString *) *components; OFMutableArray OF_GENERIC(OFString *) *array; OFString *ret; bool done = false; if (self.length == 0) return @""; components = self.pathComponents; if (components.count == 1) { objc_autoreleasePoolPop(pool); return [[self copy] autorelease]; } array = [[components mutableCopy] autorelease]; while (!done) { size_t length = array.count; done = true; for (size_t i = 0; i < length; i++) { OFString *component = [array objectAtIndex: i]; OFString *parent = (i > 0 ? [array objectAtIndex: i - 1] : 0); if ([component isEqual: @"."] || component.length == 0) { [array removeObjectAtIndex: i]; done = false; break; } if ([component isEqual: @".."] && parent != nil && ![parent isEqual: @".."] && ![parent hasSuffix: @":"] && ![parent hasSuffix: @":\\"] && ![parent hasSuffix: @"://"] && (![parent hasPrefix: @"\\"] || i != 1)) { [array removeObjectsInRange: of_range(i - 1, 2)]; done = false; break; } } } ret = [[OFString pathWithComponents: array] retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFString *)stringByAppendingPathComponent: (OFString *)component { if ([self hasSuffix: @"\\"] || [self hasSuffix: @"/"]) return [self stringByAppendingString: component]; else { OFMutableString *ret = [[self mutableCopy] autorelease]; [ret appendString: @"\\"]; [ret appendString: component]; [ret makeImmutable]; return ret; } } @end |
Added src/platform/windows/condition.m version [848a636ef0].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 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 140 141 142 143 144 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <errno.h> #import "condition.h" #include <windows.h> bool of_condition_new(of_condition_t *condition) { condition->count = 0; if ((condition->event = CreateEvent(NULL, FALSE, 0, NULL)) == NULL) { errno = EAGAIN; return false; } return true; } bool of_condition_signal(of_condition_t *condition) { if (!SetEvent(condition->event)) { switch (GetLastError()) { case ERROR_INVALID_HANDLE: errno = EINVAL; return false; default: OF_ENSURE(0); } } return true; } bool of_condition_broadcast(of_condition_t *condition) { int count = condition->count; for (int i = 0; i < count; i++) { if (!SetEvent(condition->event)) { switch (GetLastError()) { case ERROR_INVALID_HANDLE: errno = EINVAL; return false; default: OF_ENSURE(0); } } } return true; } bool of_condition_wait(of_condition_t *condition, of_mutex_t *mutex) { DWORD status; if (!of_mutex_unlock(mutex)) return false; of_atomic_int_inc(&condition->count); status = WaitForSingleObject(condition->event, INFINITE); of_atomic_int_dec(&condition->count); switch (status) { case WAIT_OBJECT_0: return of_mutex_lock(mutex); case WAIT_FAILED: switch (GetLastError()) { case ERROR_INVALID_HANDLE: errno = EINVAL; return false; default: OF_ENSURE(0); } default: OF_ENSURE(0); } } bool of_condition_timed_wait(of_condition_t *condition, of_mutex_t *mutex, of_time_interval_t timeout) { DWORD status; if (!of_mutex_unlock(mutex)) return false; of_atomic_int_inc(&condition->count); status = WaitForSingleObject(condition->event, timeout * 1000); of_atomic_int_dec(&condition->count); switch (status) { case WAIT_OBJECT_0: return of_mutex_lock(mutex); case WAIT_TIMEOUT: errno = ETIMEDOUT; return false; case WAIT_FAILED: switch (GetLastError()) { case ERROR_INVALID_HANDLE: errno = EINVAL; return false; default: OF_ENSURE(0); } default: OF_ENSURE(0); } } bool of_condition_free(of_condition_t *condition) { if (condition->count != 0) { errno = EBUSY; return false; } return CloseHandle(condition->event); } |
Added src/platform/windows/mutex.m version [c67aeb237e].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 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 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <errno.h> #import "mutex.h" #include <windows.h> bool of_mutex_new(of_mutex_t *mutex) { InitializeCriticalSection(mutex); return true; } bool of_mutex_lock(of_mutex_t *mutex) { EnterCriticalSection(mutex); return true; } bool of_mutex_trylock(of_mutex_t *mutex) { if (!TryEnterCriticalSection(mutex)) { errno = EBUSY; return false; } return true; } bool of_mutex_unlock(of_mutex_t *mutex) { LeaveCriticalSection(mutex); return true; } bool of_mutex_free(of_mutex_t *mutex) { DeleteCriticalSection(mutex); return true; } bool of_rmutex_new(of_rmutex_t *rmutex) { return of_mutex_new(rmutex); } bool of_rmutex_lock(of_rmutex_t *rmutex) { return of_mutex_lock(rmutex); } bool of_rmutex_trylock(of_rmutex_t *rmutex) { return of_mutex_trylock(rmutex); } bool of_rmutex_unlock(of_rmutex_t *rmutex) { return of_mutex_unlock(rmutex); } bool of_rmutex_free(of_rmutex_t *rmutex) { return of_mutex_free(rmutex); } |
Added src/platform/windows/thread.m version [890723e850].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 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 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <errno.h> #import "thread.h" #import "macros.h" #include <windows.h> bool of_thread_attr_init(of_thread_attr_t *attr) { attr->priority = 0; attr->stackSize = 0; return true; } bool of_thread_new(of_thread_t *thread, const char *name, void (*function)(id), id object, const of_thread_attr_t *attr) { *thread = CreateThread(NULL, (attr != NULL ? attr->stackSize : 0), (LPTHREAD_START_ROUTINE)function, (void *)object, 0, NULL); if (thread == NULL) { switch (GetLastError()) { case ERROR_NOT_ENOUGH_MEMORY: errno = ENOMEM; return false; case ERROR_ACCESS_DENIED: errno = EACCES; return false; default: OF_ENSURE(0); } } if (attr != NULL && attr->priority != 0) { DWORD priority; if (attr->priority < -1 || attr->priority > 1) { errno = EINVAL; return false; } if (attr->priority < 0) priority = THREAD_PRIORITY_LOWEST + (1.0 + attr->priority) * (THREAD_PRIORITY_NORMAL - THREAD_PRIORITY_LOWEST); else priority = THREAD_PRIORITY_NORMAL + attr->priority * (THREAD_PRIORITY_HIGHEST - THREAD_PRIORITY_NORMAL); OF_ENSURE(!SetThreadPriority(*thread, priority)); } return true; } bool of_thread_join(of_thread_t thread) { switch (WaitForSingleObject(thread, INFINITE)) { case WAIT_OBJECT_0: CloseHandle(thread); return true; case WAIT_FAILED: switch (GetLastError()) { case ERROR_INVALID_HANDLE: errno = EINVAL; return false; default: OF_ENSURE(0); } default: OF_ENSURE(0); } } bool of_thread_detach(of_thread_t thread) { CloseHandle(thread); return true; } void of_thread_set_name(const char *name) { } |
Added src/platform/windows/tlskey.m version [c8aecc8bc3].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "tlskey.h" bool of_tlskey_new(of_tlskey_t *key) { return ((*key = TlsAlloc()) != TLS_OUT_OF_INDEXES); } bool of_tlskey_free(of_tlskey_t key) { return TlsFree(key); } |
Modified src/thread.m from [38b0fd07ce] to [5fe1003cc7].
︙ | ︙ | |||
13 14 15 16 17 18 19 | * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" | | | | | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include "platform.h" #if defined(OF_HAVE_PTHREADS) # include "platform/posix/thread.m" #elif defined(OF_WINDOWS) # include "platform/windows/thread.m" #elif defined(OF_AMIGAOS) # include "platform/amiga/thread.m" #endif |
Deleted src/thread_amiga.m version [771368e5cf].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/thread_pthread.m version [f19e7d8433].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/thread_winapi.m version [5d4798ca28].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Modified src/tlskey.m from [dccef5e723] to [abedce4e93].
︙ | ︙ | |||
13 14 15 16 17 18 19 | * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" | < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include "platform.h" #if defined(OF_HAVE_PTHREADS) # include "platform/posix/tlskey.m" #elif defined(OF_WINDOWS) # include "platform/windows/tlskey.m" #elif defined(OF_AMIGAOS) # include "platform/amiga/tlskey.m" #endif |