ObjFW  Check-in [846125bed6]

Overview
Comment:Fix async connect with epoll
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 846125bed62e420787761ab0af462a4b4d64dbc83e6fee3e890baabdceab03aa
User & Date: js on 2019-09-07 23:28:50
Other Links: manifest | tags
Context
2019-09-07
23:33
ofhttp: Fix error code not always being set check-in: 9764b0886f user: js tags: trunk
23:28
Fix async connect with epoll check-in: 846125bed6 user: js tags: trunk
2019-09-01
18:50
condition.h: Remove OF_ASSUME_NONNULL_{BEGIN,END} check-in: 35b6a34c32 user: js tags: trunk
Changes

Modified src/OFEpollKernelEventObserver.m from [5cdf80c1e6] to [06e819f56f].

126
127
128
129
130
131
132






133
134
135



136
137
138
139
140
141
142
126
127
128
129
130
131
132
133
134
135
136
137
138



139
140
141
142
143
144
145
146
147
148







+
+
+
+
+
+
-
-
-
+
+
+








	events = (intptr_t)[_FDToEvents
	    objectForKey: (void *)((intptr_t)fd + 1)];
	events &= ~removeEvents;

	if (events == 0) {
		if (epoll_ctl(_epfd, EPOLL_CTL_DEL, fd, NULL) == -1)
			/*
			 * When an async connect fails, it seems the socket is
			 * automatically removed from epoll, meaning ENOENT is
			 * returned when we try to remove it after it failed.
			 */
			if (errno != ENOENT)
			@throw [OFObserveFailedException
			    exceptionWithObserver: self
					    errNo: errno];
				@throw [OFObserveFailedException
				    exceptionWithObserver: self
						    errNo: errno];

		[_FDToEvents removeObjectForKey: (void *)((intptr_t)fd + 1)];
	} else {
		struct epoll_event event;

		memset(&event, 0, sizeof(event));
		event.events = (int)events;

Modified src/OFRunLoop.m from [747027d6fd] to [d7aa5cb83d].

700
701
702
703
704
705
706
707
708
709






















710
711
712
713
714
715
716
700
701
702
703
704
705
706



707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735







-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







		exception = [OFConnectionFailedException
		    exceptionWithHost: nil
				 port: 0
			       socket: object
				errNo: errNo];

	if ([_delegate respondsToSelector:
	    @selector(of_socketDidConnect:exception:)])
		[_delegate of_socketDidConnect: object
				     exception: exception];
	    @selector(of_socketDidConnect:exception:)]) {
		/*
		 * Make sure we only call the delegate once we removed the
		 * socket from the kernel event observer. This is necessary as
		 * otherwise we could try to connect to the next address and it
		 * would not be re-registered with the kernel event observer,
		 * which is necessary for some kernel event observers (e.g.
		 * epoll) even if the fd of the new socket is the same.
		 */
		OFRunLoop *runLoop = [OFRunLoop currentRunLoop];
		OFTimer *timer = [OFTimer
		    timerWithTimeInterval: 0
				   target: _delegate
				 selector: @selector(of_socketDidConnect:
					       exception:)
				   object: object
				   object: exception
				  repeats: false];

		[runLoop addTimer: timer
			  forMode: runLoop.currentMode];
	}

	return false;
}
@end
# endif

@implementation OFRunLoopAcceptQueueItem