@@ -171,9 +171,102 @@ WaitEventSet *FeBeWaitSet;
171
171
void
172
172
pq_init (void )
173
173
{
174
+ Port * port = MyProcPort ;
174
175
int socket_pos PG_USED_FOR_ASSERTS_ONLY ;
175
176
int latch_pos PG_USED_FOR_ASSERTS_ONLY ;
176
177
178
+ /* fill in the server (local) address */
179
+ port -> laddr .salen = sizeof (port -> laddr .addr );
180
+ if (getsockname (port -> sock ,
181
+ (struct sockaddr * ) & port -> laddr .addr ,
182
+ & port -> laddr .salen ) < 0 )
183
+ {
184
+ ereport (FATAL ,
185
+ (errmsg ("%s() failed: %m" , "getsockname" )));
186
+ }
187
+
188
+ /* select NODELAY and KEEPALIVE options if it's a TCP connection */
189
+ if (port -> laddr .addr .ss_family != AF_UNIX )
190
+ {
191
+ int on ;
192
+ #ifdef WIN32
193
+ int oldopt ;
194
+ int optlen ;
195
+ int newopt ;
196
+ #endif
197
+
198
+ #ifdef TCP_NODELAY
199
+ on = 1 ;
200
+ if (setsockopt (port -> sock , IPPROTO_TCP , TCP_NODELAY ,
201
+ (char * ) & on , sizeof (on )) < 0 )
202
+ {
203
+ ereport (FATAL ,
204
+ (errmsg ("%s(%s) failed: %m" , "setsockopt" , "TCP_NODELAY" )));
205
+ }
206
+ #endif
207
+ on = 1 ;
208
+ if (setsockopt (port -> sock , SOL_SOCKET , SO_KEEPALIVE ,
209
+ (char * ) & on , sizeof (on )) < 0 )
210
+ {
211
+ ereport (FATAL ,
212
+ (errmsg ("%s(%s) failed: %m" , "setsockopt" , "SO_KEEPALIVE" )));
213
+ }
214
+
215
+ #ifdef WIN32
216
+
217
+ /*
218
+ * This is a Win32 socket optimization. The OS send buffer should be
219
+ * large enough to send the whole Postgres send buffer in one go, or
220
+ * performance suffers. The Postgres send buffer can be enlarged if a
221
+ * very large message needs to be sent, but we won't attempt to
222
+ * enlarge the OS buffer if that happens, so somewhat arbitrarily
223
+ * ensure that the OS buffer is at least PQ_SEND_BUFFER_SIZE * 4.
224
+ * (That's 32kB with the current default).
225
+ *
226
+ * The default OS buffer size used to be 8kB in earlier Windows
227
+ * versions, but was raised to 64kB in Windows 2012. So it shouldn't
228
+ * be necessary to change it in later versions anymore. Changing it
229
+ * unnecessarily can even reduce performance, because setting
230
+ * SO_SNDBUF in the application disables the "dynamic send buffering"
231
+ * feature that was introduced in Windows 7. So before fiddling with
232
+ * SO_SNDBUF, check if the current buffer size is already large enough
233
+ * and only increase it if necessary.
234
+ *
235
+ * See https://support.microsoft.com/kb/823764/EN-US/ and
236
+ * https://msdn.microsoft.com/en-us/library/bb736549%28v=vs.85%29.aspx
237
+ */
238
+ optlen = sizeof (oldopt );
239
+ if (getsockopt (port -> sock , SOL_SOCKET , SO_SNDBUF , (char * ) & oldopt ,
240
+ & optlen ) < 0 )
241
+ {
242
+ ereport (FATAL ,
243
+ (errmsg ("%s(%s) failed: %m" , "getsockopt" , "SO_SNDBUF" )));
244
+ }
245
+ newopt = PQ_SEND_BUFFER_SIZE * 4 ;
246
+ if (oldopt < newopt )
247
+ {
248
+ if (setsockopt (port -> sock , SOL_SOCKET , SO_SNDBUF , (char * ) & newopt ,
249
+ sizeof (newopt )) < 0 )
250
+ {
251
+ ereport (FATAL ,
252
+ (errmsg ("%s(%s) failed: %m" , "setsockopt" , "SO_SNDBUF" )));
253
+ }
254
+ }
255
+ #endif
256
+
257
+ /*
258
+ * Also apply the current keepalive parameters. If we fail to set a
259
+ * parameter, don't error out, because these aren't universally
260
+ * supported. (Note: you might think we need to reset the GUC
261
+ * variables to 0 in such a case, but it's not necessary because the
262
+ * show hooks for these variables report the truth anyway.)
263
+ */
264
+ (void ) pq_setkeepalivesidle (tcp_keepalives_idle , port );
265
+ (void ) pq_setkeepalivesinterval (tcp_keepalives_interval , port );
266
+ (void ) pq_setkeepalivescount (tcp_keepalives_count , port );
267
+ (void ) pq_settcpusertimeout (tcp_user_timeout , port );
268
+ }
269
+
177
270
/* initialize state variables */
178
271
PqSendBufferSize = PQ_SEND_BUFFER_SIZE ;
179
272
PqSendBuffer = MemoryContextAlloc (TopMemoryContext , PqSendBufferSize );
@@ -191,21 +284,21 @@ pq_init(void)
191
284
* writes.
192
285
*/
193
286
#ifndef WIN32
194
- if (!pg_set_noblock (MyProcPort -> sock ))
287
+ if (!pg_set_noblock (port -> sock ))
195
288
ereport (FATAL ,
196
289
(errmsg ("could not set socket to nonblocking mode: %m" )));
197
290
#endif
198
291
199
292
#ifndef WIN32
200
293
201
294
/* Don't give the socket to any subprograms we execute. */
202
- if (fcntl (MyProcPort -> sock , F_SETFD , FD_CLOEXEC ) < 0 )
295
+ if (fcntl (port -> sock , F_SETFD , FD_CLOEXEC ) < 0 )
203
296
elog (FATAL , "fcntl(F_SETFD) failed on socket: %m" );
204
297
#endif
205
298
206
299
FeBeWaitSet = CreateWaitEventSet (NULL , FeBeWaitSetNEvents );
207
300
socket_pos = AddWaitEventToSet (FeBeWaitSet , WL_SOCKET_WRITEABLE ,
208
- MyProcPort -> sock , NULL , NULL );
301
+ port -> sock , NULL , NULL );
209
302
latch_pos = AddWaitEventToSet (FeBeWaitSet , WL_LATCH_SET , PGINVALID_SOCKET ,
210
303
MyLatch , NULL );
211
304
AddWaitEventToSet (FeBeWaitSet , WL_POSTMASTER_DEATH , PGINVALID_SOCKET ,
@@ -713,103 +806,6 @@ StreamConnection(pgsocket server_fd, Port *port)
713
806
return STATUS_ERROR ;
714
807
}
715
808
716
- /* fill in the server (local) address */
717
- port -> laddr .salen = sizeof (port -> laddr .addr );
718
- if (getsockname (port -> sock ,
719
- (struct sockaddr * ) & port -> laddr .addr ,
720
- & port -> laddr .salen ) < 0 )
721
- {
722
- ereport (LOG ,
723
- (errmsg ("%s() failed: %m" , "getsockname" )));
724
- return STATUS_ERROR ;
725
- }
726
-
727
- /* select NODELAY and KEEPALIVE options if it's a TCP connection */
728
- if (port -> laddr .addr .ss_family != AF_UNIX )
729
- {
730
- int on ;
731
- #ifdef WIN32
732
- int oldopt ;
733
- int optlen ;
734
- int newopt ;
735
- #endif
736
-
737
- #ifdef TCP_NODELAY
738
- on = 1 ;
739
- if (setsockopt (port -> sock , IPPROTO_TCP , TCP_NODELAY ,
740
- (char * ) & on , sizeof (on )) < 0 )
741
- {
742
- ereport (LOG ,
743
- (errmsg ("%s(%s) failed: %m" , "setsockopt" , "TCP_NODELAY" )));
744
- return STATUS_ERROR ;
745
- }
746
- #endif
747
- on = 1 ;
748
- if (setsockopt (port -> sock , SOL_SOCKET , SO_KEEPALIVE ,
749
- (char * ) & on , sizeof (on )) < 0 )
750
- {
751
- ereport (LOG ,
752
- (errmsg ("%s(%s) failed: %m" , "setsockopt" , "SO_KEEPALIVE" )));
753
- return STATUS_ERROR ;
754
- }
755
-
756
- #ifdef WIN32
757
-
758
- /*
759
- * This is a Win32 socket optimization. The OS send buffer should be
760
- * large enough to send the whole Postgres send buffer in one go, or
761
- * performance suffers. The Postgres send buffer can be enlarged if a
762
- * very large message needs to be sent, but we won't attempt to
763
- * enlarge the OS buffer if that happens, so somewhat arbitrarily
764
- * ensure that the OS buffer is at least PQ_SEND_BUFFER_SIZE * 4.
765
- * (That's 32kB with the current default).
766
- *
767
- * The default OS buffer size used to be 8kB in earlier Windows
768
- * versions, but was raised to 64kB in Windows 2012. So it shouldn't
769
- * be necessary to change it in later versions anymore. Changing it
770
- * unnecessarily can even reduce performance, because setting
771
- * SO_SNDBUF in the application disables the "dynamic send buffering"
772
- * feature that was introduced in Windows 7. So before fiddling with
773
- * SO_SNDBUF, check if the current buffer size is already large enough
774
- * and only increase it if necessary.
775
- *
776
- * See https://support.microsoft.com/kb/823764/EN-US/ and
777
- * https://msdn.microsoft.com/en-us/library/bb736549%28v=vs.85%29.aspx
778
- */
779
- optlen = sizeof (oldopt );
780
- if (getsockopt (port -> sock , SOL_SOCKET , SO_SNDBUF , (char * ) & oldopt ,
781
- & optlen ) < 0 )
782
- {
783
- ereport (LOG ,
784
- (errmsg ("%s(%s) failed: %m" , "getsockopt" , "SO_SNDBUF" )));
785
- return STATUS_ERROR ;
786
- }
787
- newopt = PQ_SEND_BUFFER_SIZE * 4 ;
788
- if (oldopt < newopt )
789
- {
790
- if (setsockopt (port -> sock , SOL_SOCKET , SO_SNDBUF , (char * ) & newopt ,
791
- sizeof (newopt )) < 0 )
792
- {
793
- ereport (LOG ,
794
- (errmsg ("%s(%s) failed: %m" , "setsockopt" , "SO_SNDBUF" )));
795
- return STATUS_ERROR ;
796
- }
797
- }
798
- #endif
799
-
800
- /*
801
- * Also apply the current keepalive parameters. If we fail to set a
802
- * parameter, don't error out, because these aren't universally
803
- * supported. (Note: you might think we need to reset the GUC
804
- * variables to 0 in such a case, but it's not necessary because the
805
- * show hooks for these variables report the truth anyway.)
806
- */
807
- (void ) pq_setkeepalivesidle (tcp_keepalives_idle , port );
808
- (void ) pq_setkeepalivesinterval (tcp_keepalives_interval , port );
809
- (void ) pq_setkeepalivescount (tcp_keepalives_count , port );
810
- (void ) pq_settcpusertimeout (tcp_user_timeout , port );
811
- }
812
-
813
809
return STATUS_OK ;
814
810
}
815
811
0 commit comments