ObjFW  Check-in [a40f3fc829]

Overview
Comment:Support sockets in multiple threads on AmigaOS
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: a40f3fc829a35d4bfb92a427e2197807cd164e197a3b4eee667c9fd6929293fe
User & Date: js on 2019-08-11 18:56:14
Other Links: manifest | tags
Context
2019-08-18
20:04
Small optimization for of_once() check-in: 47f08207d7 user: js tags: trunk
2019-08-11
18:56
Support sockets in multiple threads on AmigaOS check-in: a40f3fc829 user: js tags: trunk
16:27
amiga-library.m: Remove no longer needed __init_eh check-in: 07e774560c user: js tags: trunk
Changes

Modified src/OFApplication.m from [575d9d7624] to [0eab530ffc].

91
92
93
94
95
96
97




98
99
100
101
102
103
104
{
	id <OFApplicationDelegate> delegate = app.delegate;

	if ([delegate respondsToSelector: @selector(applicationWillTerminate)])
		[delegate applicationWillTerminate];

	[delegate release];




}

#define SIGNAL_HANDLER(signal)					\
	static void						\
	handle##signal(int sig)					\
	{							\
		app->_##signal##Handler(app->_delegate,		\







>
>
>
>







91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
{
	id <OFApplicationDelegate> delegate = app.delegate;

	if ([delegate respondsToSelector: @selector(applicationWillTerminate)])
		[delegate applicationWillTerminate];

	[delegate release];

#if defined(OF_HAVE_THREADS) && defined(OF_HAVE_SOCKETS) && defined(OF_AMIGAOS)
	of_socket_deinit();
#endif
}

#define SIGNAL_HANDLER(signal)					\
	static void						\
	handle##signal(int sig)					\
	{							\
		app->_##signal##Handler(app->_delegate,		\

Modified src/OFDNSResolver.m from [e6e0fe25fb] to [db347fdd7c].

51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

#ifdef OF_WINDOWS
# define interface struct
# include <iphlpapi.h>
# undef interface
#endif

#ifdef OF_AMIGAOS
# include <proto/exec.h>
# include <proto/bsdsocket.h>
#endif

#ifdef OF_NINTENDO_3DS
# include <3ds.h>
#endif

#ifndef SOCK_DNS
# define SOCK_DNS 0







<
<
|
<







51
52
53
54
55
56
57


58

59
60
61
62
63
64
65

#ifdef OF_WINDOWS
# define interface struct
# include <iphlpapi.h>
# undef interface
#endif



#import "socket_helpers.h"


#ifdef OF_NINTENDO_3DS
# include <3ds.h>
#endif

#ifndef SOCK_DNS
# define SOCK_DNS 0

Modified src/OFHTTPServer.m from [59f972c93b] to [afbff9f08f].

908
909
910
911
912
913
914

915
916
917
918
919
920
921
	if (_numberOfThreads > 1) {
		OFMutableArray *threads =
		    [OFMutableArray arrayWithCapacity: _numberOfThreads - 1];

		for (size_t i = 1; i < _numberOfThreads; i++) {
			OFHTTPServerThread *thread =
			    [OFHTTPServerThread thread];


			[thread start];
			[threads addObject: thread];
		}

		[threads makeImmutable];
		_threadPool = [threads copy];







>







908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
	if (_numberOfThreads > 1) {
		OFMutableArray *threads =
		    [OFMutableArray arrayWithCapacity: _numberOfThreads - 1];

		for (size_t i = 1; i < _numberOfThreads; i++) {
			OFHTTPServerThread *thread =
			    [OFHTTPServerThread thread];
			thread.supportsSockets = true;

			[thread start];
			[threads addObject: thread];
		}

		[threads makeImmutable];
		_threadPool = [threads copy];

Modified src/OFThread.h from [dc390a6e23] to [f242100e35].

46
47
48
49
50
51
52





53
54
55
56
57
58
59
/*!
 * @class OFThread OFThread.h ObjFW/OFThread.h
 *
 * @brief A class which provides portable threads.
 *
 * To use it, you should create a new class derived from it and reimplement
 * main.





 *
 * @warning Even though the OFCopying protocol is implemented, it does *not*
 *	    return an independent copy of the thread, but instead retains it.
 *	    This is so that the thread can be used as a key for a dictionary,
 *	    so context can be associated with a thread.
 */
@interface OFThread: OFObject







>
>
>
>
>







46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/*!
 * @class OFThread OFThread.h ObjFW/OFThread.h
 *
 * @brief A class which provides portable threads.
 *
 * To use it, you should create a new class derived from it and reimplement
 * main.
 *
 * @warning Some operating systems such as AmigaOS need special per-thread
 *	    initialization of sockets. If you intend to use sockets in the
 *	    thread, set the @ref usesSockets property to true before starting
 *	    it.
 *
 * @warning Even though the OFCopying protocol is implemented, it does *not*
 *	    return an independent copy of the thread, but instead retains it.
 *	    This is so that the thread can be used as a key for a dictionary,
 *	    so context can be associated with a thread.
 */
@interface OFThread: OFObject
72
73
74
75
76
77
78


79
80
81
82
83
84
85
	} _running;
	void *_pool;
# ifdef OF_HAVE_BLOCKS
	of_thread_block_t _Nullable _threadBlock;
# endif
	jmp_buf _exitEnv;
	id _returnValue;


	OFRunLoop *_Nullable _runLoop;
	OFMutableDictionary *_threadDictionary;
@private
	OFString *_Nullable _name;
# ifdef OF_HAVE_SOCKETS
	OFDNSResolver *_DNSResolver;
# endif







>
>







77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
	} _running;
	void *_pool;
# ifdef OF_HAVE_BLOCKS
	of_thread_block_t _Nullable _threadBlock;
# endif
	jmp_buf _exitEnv;
	id _returnValue;
@protected
	bool _supportsSockets;
	OFRunLoop *_Nullable _runLoop;
	OFMutableDictionary *_threadDictionary;
@private
	OFString *_Nullable _name;
# ifdef OF_HAVE_SOCKETS
	OFDNSResolver *_DNSResolver;
# endif
137
138
139
140
141
142
143









144
145
146
147
148
149
150
/*!
 * @brief The stack size of the thread.
 *
 * @note This has to be set before the thread is started!
 */
@property (nonatomic) size_t stackSize;










/*!
 * @brief Creates a new thread.
 *
 * @return A new, autoreleased thread
 */
+ (instancetype)thread;








>
>
>
>
>
>
>
>
>







144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/*!
 * @brief The stack size of the thread.
 *
 * @note This has to be set before the thread is started!
 */
@property (nonatomic) size_t stackSize;

/*!
 * @brief Whether the thread supports sockets.
 *
 * Some operating systems such as AmigaOS need special per-thread
 * initialization of sockets. If you intend to use sockets in the thread, set
 * this property to true before starting the thread.
 */
@property (nonatomic) bool supportsSockets;

/*!
 * @brief Creates a new thread.
 *
 * @return A new, autoreleased thread
 */
+ (instancetype)thread;

Modified src/OFThread.m from [ec9da598dc] to [d2706d56fe].

86
87
88
89
90
91
92



93
94
95
96
97
98
99

#ifdef OF_DJGPP
# define lrint(x) rint(x)
#endif

#if defined(OF_HAVE_THREADS)
# import "tlskey.h"




static of_tlskey_t threadSelfKey;
static OFThread *mainThread;

static void
callMain(id object)
{







>
>
>







86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102

#ifdef OF_DJGPP
# define lrint(x) rint(x)
#endif

#if defined(OF_HAVE_THREADS)
# import "tlskey.h"
# if defined(OF_AMIGAOS) && defined(OF_HAVE_SOCKETS)
#  import "socket.h"
# endif

static of_tlskey_t threadSelfKey;
static OFThread *mainThread;

static void
callMain(id object)
{
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
	name = thread.name;
	if (name != nil)
		of_thread_set_name(
		    [name cStringWithEncoding: [OFLocale encoding]]);
	else
		of_thread_set_name(object_getClassName(thread));








	/*
	 * Nasty workaround for thread implementations which can't return a
	 * pointer on join, or don't have a way to exit a thread.
	 */
	if (setjmp(thread->_exitEnv) == 0) {
# ifdef OF_HAVE_BLOCKS
		if (thread->_threadBlock != NULL)
			thread->_returnValue = [thread->_threadBlock() retain];
		else
# endif
			thread->_returnValue = [[thread main] retain];
	}

	[thread handleTermination];

	objc_autoreleasePoolPop(thread->_pool);
	[OFAutoreleasePool of_handleThreadTermination];






	thread->_running = OF_THREAD_WAITING_FOR_JOIN;

	[thread release];
}
#elif defined(OF_HAVE_SOCKETS)
static OFDNSResolver *DNSResolver;







>
>
>
>
>
>
>

















>
>
>
>
>







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
	name = thread.name;
	if (name != nil)
		of_thread_set_name(
		    [name cStringWithEncoding: [OFLocale encoding]]);
	else
		of_thread_set_name(object_getClassName(thread));

#if defined(OF_AMIGAOS) && defined(OF_HAVE_SOCKETS)
	if (thread.supportsSockets)
		if (!of_socket_init())
			@throw [OFInitializationFailedException
			    exceptionWithClass: thread.class];
#endif

	/*
	 * Nasty workaround for thread implementations which can't return a
	 * pointer on join, or don't have a way to exit a thread.
	 */
	if (setjmp(thread->_exitEnv) == 0) {
# ifdef OF_HAVE_BLOCKS
		if (thread->_threadBlock != NULL)
			thread->_returnValue = [thread->_threadBlock() retain];
		else
# endif
			thread->_returnValue = [[thread main] retain];
	}

	[thread handleTermination];

	objc_autoreleasePoolPop(thread->_pool);
	[OFAutoreleasePool of_handleThreadTermination];

#if defined(OF_AMIGAOS) && defined(OF_HAVE_SOCKETS)
	if (thread.supportsSockets)
		of_socket_deinit();
#endif

	thread->_running = OF_THREAD_WAITING_FOR_JOIN;

	[thread release];
}
#elif defined(OF_HAVE_SOCKETS)
static OFDNSResolver *DNSResolver;
461
462
463
464
465
466
467














468
469
470
471
472
473
474
{
	if (_running == OF_THREAD_RUNNING)
		@throw [OFThreadStillRunningException
		    exceptionWithThread: self];

	_attr.stackSize = stackSize;
}















- (void)dealloc
{
	if (_running == OF_THREAD_RUNNING)
		@throw [OFThreadStillRunningException
		    exceptionWithThread: self];








>
>
>
>
>
>
>
>
>
>
>
>
>
>







476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
{
	if (_running == OF_THREAD_RUNNING)
		@throw [OFThreadStillRunningException
		    exceptionWithThread: self];

	_attr.stackSize = stackSize;
}

- (bool)supportsSockets
{
	return _supportsSockets;
}

- (void)setSupportsSockets: (bool)supportsSockets
{
	if (_running == OF_THREAD_RUNNING)
		@throw [OFThreadStillRunningException
		    exceptionWithThread: self];

	_supportsSockets = supportsSockets;
}

- (void)dealloc
{
	if (_running == OF_THREAD_RUNNING)
		@throw [OFThreadStillRunningException
		    exceptionWithThread: self];

Modified src/socket.h from [dca04b58ae] to [a943bd03d9].

49
50
51
52
53
54
55



56
57
58
59
60
61
62
#endif

#ifdef OF_PSP
# include <stdint.h>
#endif

#import "macros.h"




OF_ASSUME_NONNULL_BEGIN

#ifndef OF_WINDOWS
typedef int of_socket_t;
#else
typedef SOCKET of_socket_t;







>
>
>







49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#endif

#ifdef OF_PSP
# include <stdint.h>
#endif

#import "macros.h"
#if defined(OF_HAVE_THREADS) && defined(OF_AMIGAOS)
# import "tlskey.h"
#endif

OF_ASSUME_NONNULL_BEGIN

#ifndef OF_WINDOWS
typedef int of_socket_t;
#else
typedef SOCKET of_socket_t;
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
	} sockaddr;
	socklen_t length;
} of_socket_address_t;

#ifdef __cplusplus
extern "C" {
#endif
extern bool of_socket_init(void);
extern int of_socket_errno(void);
# if !defined(OF_WII) && !defined(OF_NINTENDO_3DS)
extern int of_getsockname(of_socket_t sock, struct sockaddr *restrict addr,
    socklen_t *restrict addrLen);
# endif

/*!
 * @brief Parses the specified IP and port into an of_socket_address_t.
 *
 * @param IP The IP to parse
 * @param port The port to use
 * @return The parsed IP and port as an of_socket_address_t
 */







<
<
<
<
<
<
<







126
127
128
129
130
131
132







133
134
135
136
137
138
139
	} sockaddr;
	socklen_t length;
} of_socket_address_t;

#ifdef __cplusplus
extern "C" {
#endif







/*!
 * @brief Parses the specified IP and port into an of_socket_address_t.
 *
 * @param IP The IP to parse
 * @param port The port to use
 * @return The parsed IP and port as an of_socket_address_t
 */
212
213
214
215
216
217
218

















219
220
221
222
223
 *	  the address family used.
 *
 * @param address The address on which to get the port
 * @return The port of the address
 */
extern uint16_t of_socket_address_get_port(
    const of_socket_address_t *_Nonnull address);

















#ifdef __cplusplus
}
#endif

OF_ASSUME_NONNULL_END







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





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
 *	  the address family used.
 *
 * @param address The address on which to get the port
 * @return The port of the address
 */
extern uint16_t of_socket_address_get_port(
    const of_socket_address_t *_Nonnull address);

extern bool of_socket_init(void);
#if defined(OF_HAVE_THREADS) && defined(OF_AMIGAOS)
extern void of_socket_deinit(void);
#endif
extern int of_socket_errno(void);
#if !defined(OF_WII) && !defined(OF_NINTENDO_3DS)
extern int of_getsockname(of_socket_t sock, struct sockaddr *restrict addr,
    socklen_t *restrict addrLen);
#endif

#if defined(OF_HAVE_THREADS) && defined(OF_AMIGAOS)
extern of_tlskey_t of_socket_base_key;
# ifdef OF_AMIGAOS4
extern of_tlskey_t of_socket_interface_key;
# endif
#endif
#ifdef __cplusplus
}
#endif

OF_ASSUME_NONNULL_END

Modified src/socket.m from [54314146cb] to [b18a1905f9].

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

#import "OFArray.h"
#import "OFCharacterSet.h"
#import "OFLocale.h"
#import "OFString.h"

#import "OFException.h"  /* For some E* -> WSAE* defines */

#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "OFLockFailedException.h"
#import "OFUnlockFailedException.h"

#import "socket.h"
#import "socket_helpers.h"
#ifdef OF_HAVE_THREADS

# include "mutex.h"



#endif
#include "once.h"

#ifdef OF_AMIGAOS
# include <proto/exec.h>
#endif

#ifdef OF_NINTENDO_3DS
# include <3ds/types.h>
# include <3ds/services/soc.h>
#endif

#ifdef OF_HAVE_THREADS
static of_mutex_t mutex;
#endif
#ifdef OF_AMIGAOS
/* TODO: Support multiple threads */







struct Library *SocketBase;
# ifdef OF_AMIGAOS4
struct SocketIFace *ISocket = NULL;

# endif
#endif
static bool initSuccessful = false;














static void
init(void)
{
#if defined(OF_WINDOWS)
	WSADATA wsa;

	if (WSAStartup(MAKEWORD(2, 0), &wsa))
		return;
#elif defined(OF_AMIGAOS)
	if ((SocketBase = OpenLibrary("bsdsocket.library", 4)) == NULL)
		return;

# ifdef OF_AMIGAOS4
	if ((ISocket = (struct SocketIFace *)
	    GetInterface(SocketBase, "main", 1, NULL)) == NULL) {
		CloseLibrary(SocketBase);
		return;
	}
# endif
#elif defined(OF_WII)
	if (net_init() < 0)
		return;
#elif defined(OF_NINTENDO_3DS)
	void *ctx;

	if ((ctx = memalign(0x1000, 0x100000)) == NULL)
		return;

	if (socInit(ctx, 0x100000) != 0)
		return;

	atexit((void (*)(void))socExit);
#endif

#ifdef OF_HAVE_THREADS
	if (!of_mutex_new(&mutex))
		return;

# ifdef OF_WII
	if (!of_spinlock_new(&spinlock))
		return;
# endif
#endif

	initSuccessful = true;
}

#ifdef OF_AMIGAOS
OF_DESTRUCTOR()
{
# ifdef OF_AMIGAOS4
	if (ISocket != NULL)
		DropInterface((struct Interface *)ISocket);
# endif

	if (SocketBase != NULL)
		CloseLibrary(SocketBase);
}

#endif

bool
of_socket_init()
{

	static of_once_t onceControl = OF_ONCE_INIT;
	of_once(&onceControl, init);

	return initSuccessful;





}























































int
of_socket_errno()
{
#if defined(OF_WINDOWS)
	switch (WSAGetLastError()) {
	case WSAEACCES:







>








>
|
>
>
>












|


|
|
>
>
>
>
>
>
>

|

>


|
>
>
|
>
>
>
>
>
>
>
>
>
>
>



|




|



|





|
|


|









|

|



|


|
|




|


|


|




>



|

>




>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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

#import "OFArray.h"
#import "OFCharacterSet.h"
#import "OFLocale.h"
#import "OFString.h"

#import "OFException.h"  /* For some E* -> WSAE* defines */
#import "OFInitializationFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "OFLockFailedException.h"
#import "OFUnlockFailedException.h"

#import "socket.h"
#import "socket_helpers.h"
#ifdef OF_HAVE_THREADS
# ifndef OF_AMIGAOS
#  import "mutex.h"
# else
#  import "tlskey.h"
# endif
#endif
#include "once.h"

#ifdef OF_AMIGAOS
# include <proto/exec.h>
#endif

#ifdef OF_NINTENDO_3DS
# include <3ds/types.h>
# include <3ds/services/soc.h>
#endif

#if defined(OF_HAVE_THREADS) && !defined(OF_AMIGAOS)
static of_mutex_t mutex;
#endif
#ifndef OF_AMIGAOS
static bool initSuccessful = false;
#else
# ifdef OF_HAVE_THREADS
of_tlskey_t of_socket_base_key;
#  ifdef OF_AMIGAOS4
of_tlskey_t of_socket_interface_key;
#  endif
# else
struct Library *SocketBase;
#  ifdef OF_AMIGAOS4
struct SocketIFace *ISocket = NULL;
#  endif
# endif
#endif

#if defined(OF_HAVE_THREADS) && defined(OF_AMIGAOS)
OF_CONSTRUCTOR()
{
	if (!of_tlskey_new(&of_socket_base_key))
		@throw [OFInitializationFailedException exception];

# ifdef OF_AMIGAOS4
	if (!of_tlskey_new(&of_socket_interface_key))
		@throw [OFInitializationFailedException exception];
# endif
}
#endif

#if !defined(OF_AMIGAOS) || !defined(OF_HAVE_THREADS)
static void
init(void)
{
# if defined(OF_WINDOWS)
	WSADATA wsa;

	if (WSAStartup(MAKEWORD(2, 0), &wsa))
		return;
# elif defined(OF_AMIGAOS)
	if ((SocketBase = OpenLibrary("bsdsocket.library", 4)) == NULL)
		return;

#  ifdef OF_AMIGAOS4
	if ((ISocket = (struct SocketIFace *)
	    GetInterface(SocketBase, "main", 1, NULL)) == NULL) {
		CloseLibrary(SocketBase);
		return;
	}
#  endif
# elif defined(OF_WII)
	if (net_init() < 0)
		return;
# elif defined(OF_NINTENDO_3DS)
	void *ctx;

	if ((ctx = memalign(0x1000, 0x100000)) == NULL)
		return;

	if (socInit(ctx, 0x100000) != 0)
		return;

	atexit((void (*)(void))socExit);
# endif

# if defined(OF_HAVE_THREADS) && !defined(OF_AMIGAOS)
	if (!of_mutex_new(&mutex))
		return;

#  ifdef OF_WII
	if (!of_spinlock_new(&spinlock))
		return;
#  endif
# endif

	initSuccessful = true;
}

# ifdef OF_AMIGAOS
OF_DESTRUCTOR()
{
#  ifdef OF_AMIGAOS4
	if (ISocket != NULL)
		DropInterface((struct Interface *)ISocket);
#  endif

	if (SocketBase != NULL)
		CloseLibrary(SocketBase);
}
# endif
#endif

bool
of_socket_init(void)
{
#if !defined(OF_AMIGAOS) || !defined(OF_HAVE_THREADS)
	static of_once_t onceControl = OF_ONCE_INIT;
	of_once(&onceControl, init);

	return initSuccessful;
#else
	struct Library *socketBase;
# ifdef OF_AMIGAOS4
	struct SocketIFace *socketInterface;
# endif

# ifdef OF_AMIGAOS4
	if ((socketInterface = of_tlskey_get(of_socket_interface_key)) != NULL)
# else
	if ((socketBase = of_tlskey_get(of_socket_base_key)) != NULL)
# endif
		return true;

	if ((socketBase = OpenLibrary("bsdsocket.library", 4)) == NULL)
		return false;

# ifdef OF_AMIGAOS4
	if ((socketInterface = (struct SocketIFace *)
	    GetInterface(socketBase, "main", 1, NULL)) == NULL) {
		CloseLibrary(socketBase);
		return false;
	}
# endif

	if (!of_tlskey_set(of_socket_base_key, socketBase)) {
		CloseLibrary(socketBase);
# ifdef OF_AMIGAOS4
		DropInterface((struct Interface *)socketInterface);
# endif
		return false;
	}

# ifdef OF_AMIGAOS4
	if (!of_tlskey_set(of_socket_interface_key, socketInterface)) {
		CloseLibrary(socketBase);
		DropInterface((struct Interface *)socketInterface);
		return false;
	}
# endif

	return true;
#endif
}

#if defined(OF_HAVE_THREADS) && defined(OF_AMIGAOS)
void
of_socket_deinit(void)
{
	struct Library *socketBase = of_tlskey_get(of_socket_base_key);
# ifdef OF_AMIGAOS4
	struct SocketIFace *socketInterface =
	    of_tlskey_get(of_socket_interface_key);

	if (socketInterface != NULL)
		DropInterface((struct Interface *)socketInterface);
# endif
	if (socketBase != NULL)
		CloseLibrary(socketBase);
}
#endif

int
of_socket_errno()
{
#if defined(OF_WINDOWS)
	switch (WSAGetLastError()) {
	case WSAEACCES:
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
#ifndef OF_WII
int
of_getsockname(of_socket_t sock, struct sockaddr *restrict addr,
    socklen_t *restrict addrLen)
{
	int ret;

# ifdef OF_HAVE_THREADS
	if (!of_mutex_lock(&mutex))
		@throw [OFLockFailedException exception];

# endif

	ret = getsockname(sock, addr, addrLen);

# ifdef OF_HAVE_THREADS
	if (!of_mutex_unlock(&mutex))
		@throw [OFUnlockFailedException exception];
# endif

	return ret;
}
#endif







|







|







322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
#ifndef OF_WII
int
of_getsockname(of_socket_t sock, struct sockaddr *restrict addr,
    socklen_t *restrict addrLen)
{
	int ret;

# if defined(OF_HAVE_THREADS) && !defined(OF_AMIGAOS)
	if (!of_mutex_lock(&mutex))
		@throw [OFLockFailedException exception];

# endif

	ret = getsockname(sock, addr, addrLen);

# if defined(OF_HAVE_THREADS) && !defined(OF_AMIGAOS)
	if (!of_mutex_unlock(&mutex))
		@throw [OFUnlockFailedException exception];
# endif

	return ret;
}
#endif

Modified src/socket_helpers.h from [611aa62b04] to [2c4f4edda3].

51
52
53
54
55
56
57







58
59
60
61
62
63
64
#if defined(OF_AMIGAOS)
# include <proto/bsdsocket.h>
# include <sys/filio.h>
# define closesocket(sock) CloseSocket(sock)
# define ioctlsocket(fd, req, arg) IoctlSocket(fd, req, arg)
# define hstrerror(err) "unknown (no hstrerror)"
# define SOCKET_ERROR -1







# ifdef OF_MORPHOS
typedef uint32_t in_addr_t;
# endif
#elif !defined(OF_WINDOWS) && !defined(OF_WII)
# define closesocket(sock) close(sock)
#endif








>
>
>
>
>
>
>







51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#if defined(OF_AMIGAOS)
# include <proto/bsdsocket.h>
# include <sys/filio.h>
# define closesocket(sock) CloseSocket(sock)
# define ioctlsocket(fd, req, arg) IoctlSocket(fd, req, arg)
# define hstrerror(err) "unknown (no hstrerror)"
# define SOCKET_ERROR -1
# ifdef OF_HAVE_THREADS
#  define SocketBase ((struct Library *)of_tlskey_get(of_socket_base_key))
#  ifdef OF_AMIGAOS4
#   define ISocket \
	((struct SocketIFace *)of_tlskey_get(of_socket_interface_key))
#  endif
# endif
# ifdef OF_MORPHOS
typedef uint32_t in_addr_t;
# endif
#elif !defined(OF_WINDOWS) && !defined(OF_WII)
# define closesocket(sock) close(sock)
#endif

Modified tests/OFHTTPClientTests.m from [a26978f51b] to [3c6e718237].

116
117
118
119
120
121
122

123
124
125
126
127
128
129
	OFHTTPRequest *request;
	OFData *data;

	cond = [OFCondition condition];
	[cond lock];

	server = [[[HTTPClientTestsServer alloc] init] autorelease];

	[server start];

	[cond wait];
	[cond unlock];

	URL = [OFURL URLWithString:
	    [OFString stringWithFormat: @"http://127.0.0.1:%" @PRIu16 "/foo",







>







116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
	OFHTTPRequest *request;
	OFData *data;

	cond = [OFCondition condition];
	[cond lock];

	server = [[[HTTPClientTestsServer alloc] init] autorelease];
	server.supportsSockets = true;
	[server start];

	[cond wait];
	[cond unlock];

	URL = [OFURL URLWithString:
	    [OFString stringWithFormat: @"http://127.0.0.1:%" @PRIu16 "/foo",