@@ -34,6 +34,8 @@ final class SocketIpcHub implements IpcHub
34
34
/** @var \Closure(): void */
35
35
private readonly \Closure $ accept ;
36
36
37
+ private bool $ queued = false ;
38
+
37
39
/**
38
40
* @param float $keyReceiveTimeout Timeout to receive the key on accepted connections.
39
41
* @param positive-int $keyLength Length of the random key exchanged on the IPC channel when connecting.
@@ -49,10 +51,28 @@ public function __construct(
49
51
SocketAddressType::Internet => 'tcp:// ' . $ address ->toString (),
50
52
};
51
53
54
+ $ queued = &$ this ->queued ;
52
55
$ keys = &$ this ->keys ;
53
56
$ pending = &$ this ->pending ;
54
- $ this ->accept = static function () use (&$ keys , &$ pending , $ server , $ keyReceiveTimeout , $ keyLength ): void {
55
- while ($ pending && $ client = $ server ->accept ()) {
57
+ $ this ->accept = static function () use (
58
+ &$ queued ,
59
+ &$ keys ,
60
+ &$ pending ,
61
+ $ server ,
62
+ $ keyReceiveTimeout ,
63
+ $ keyLength ,
64
+ ): void {
65
+ while ($ pending ) {
66
+ $ client = $ server ->accept ();
67
+ if (!$ client ) {
68
+ $ queued = false ;
69
+ $ exception = new Socket \SocketException ('IPC socket closed before the client connected ' );
70
+ foreach ($ pending as $ deferred ) {
71
+ $ deferred ->error ($ exception );
72
+ }
73
+ return ;
74
+ }
75
+
56
76
try {
57
77
$ received = readKey ($ client , new TimeoutCancellation ($ keyReceiveTimeout ), $ keyLength );
58
78
} catch (\Throwable ) {
@@ -77,6 +97,8 @@ public function __construct(
77
97
78
98
$ deferred ->complete ($ client );
79
99
}
100
+
101
+ $ queued = false ;
80
102
};
81
103
}
82
104
@@ -124,6 +146,10 @@ public function generateKey(): string
124
146
*/
125
147
public function accept (string $ key , ?Cancellation $ cancellation = null ): ResourceSocket
126
148
{
149
+ if ($ this ->server ->isClosed ()) {
150
+ throw new Socket \SocketException ('The IPC server has been closed ' );
151
+ }
152
+
127
153
if (\strlen ($ key ) !== $ this ->keyLength ) {
128
154
throw new \ValueError (\sprintf (
129
155
"Key provided is of length %d, expected %d " ,
@@ -138,12 +164,13 @@ public function accept(string $key, ?Cancellation $cancellation = null): Resourc
138
164
139
165
$ id = $ this ->nextId ++;
140
166
141
- if (!$ this ->pending ) {
167
+ if (!$ this ->queued ) {
142
168
EventLoop::queue ($ this ->accept );
169
+ $ this ->queued = true ;
143
170
}
144
171
145
172
$ this ->keys [$ key ] = $ id ;
146
- $ this ->pending [$ id ] = $ deferred = new DeferredFuture ;
173
+ $ this ->pending [$ id ] = $ deferred = new DeferredFuture () ;
147
174
148
175
try {
149
176
$ client = $ deferred ->getFuture ()->await ($ cancellation );
0 commit comments