@@ -119,22 +119,12 @@ _mongoc_socket_wait (int sd, /* IN */
119
119
#endif
120
120
int ret ;
121
121
int timeout ;
122
+ int64_t now ;
122
123
123
124
ENTRY ;
124
125
125
126
bson_return_val_if_fail (events , false);
126
127
127
- if (expire_at < 0 ) {
128
- timeout = -1 ;
129
- } else if (expire_at == 0 ) {
130
- timeout = 0 ;
131
- } else {
132
- timeout = (int )((expire_at - bson_get_monotonic_time ()) / 1000L );
133
- if (timeout < 0 ) {
134
- timeout = 0 ;
135
- }
136
- }
137
-
138
128
pfd .fd = sd ;
139
129
#ifdef _WIN32
140
130
pfd .events = events ;
@@ -143,25 +133,57 @@ _mongoc_socket_wait (int sd, /* IN */
143
133
#endif
144
134
pfd .revents = 0 ;
145
135
136
+ now = bson_get_monotonic_time ();
137
+
138
+ for (;;) {
139
+ if (expire_at < 0 ) {
140
+ timeout = -1 ;
141
+ } else if (expire_at == 0 ) {
142
+ timeout = 0 ;
143
+ } else {
144
+ timeout = (int )((expire_at - now ) / 1000L );
145
+ if (timeout < 0 ) {
146
+ timeout = 0 ;
147
+ }
148
+ }
149
+
146
150
#ifdef _WIN32
147
- ret = WSAPoll (& pfd , 1 , timeout );
148
- if (ret == SOCKET_ERROR ) {
149
- MONGOC_WARNING ( "WSAGetLastError(): %d" , WSAGetLastError () );
150
- ret = false ;
151
- }
151
+ ret = WSAPoll (& pfd , 1 , timeout );
152
+ if (ret == SOCKET_ERROR ) {
153
+ errno = WSAGetLastError ( );
154
+ ret = -1 ;
155
+ }
152
156
#else
153
- ret = poll (& pfd , 1 , timeout );
157
+ ret = poll (& pfd , 1 , timeout );
154
158
#endif
155
159
156
- if (ret > 0 ) {
160
+ if (ret > 0 ) {
161
+ /* Something happened, so return that */
157
162
#ifdef _WIN32
158
- RETURN (0 != (pfd .revents & (events | POLLHUP | POLLERR )));
163
+ RETURN (0 != (pfd .revents & (events | POLLHUP | POLLERR )));
159
164
#else
160
- RETURN (0 != (pfd .revents & events ));
165
+ RETURN (0 != (pfd .revents & events ));
161
166
#endif
162
- }
167
+ } else if (ret < 0 ) {
168
+ /* poll itself failed */
163
169
164
- RETURN (false);
170
+ if (MONGOC_ERRNO_IS_AGAIN (errno )) {
171
+ now = bson_get_monotonic_time ();
172
+
173
+ if (expire_at < now ) {
174
+ RETURN (false);
175
+ } else {
176
+ continue ;
177
+ }
178
+ } else {
179
+ /* poll failed for some non-transient reason */
180
+ RETURN (false);
181
+ }
182
+ } else {
183
+ /* poll timed out */
184
+ RETURN (false);
185
+ }
186
+ }
165
187
}
166
188
167
189
@@ -417,16 +439,18 @@ mongoc_socket_close (mongoc_socket_t *sock) /* IN */
417
439
if (sock -> sd != INVALID_SOCKET ) {
418
440
shutdown (sock -> sd , SD_BOTH );
419
441
ret = closesocket (sock -> sd );
442
+ } else {
443
+ RETURN (0 );
420
444
}
421
445
#else
422
446
if (sock -> sd != -1 ) {
423
447
shutdown (sock -> sd , SHUT_RDWR );
424
448
ret = close (sock -> sd );
449
+ } else {
450
+ RETURN (0 );
425
451
}
426
452
#endif
427
453
428
- _mongoc_socket_capture_errno (sock );
429
-
430
454
if (ret == 0 ) {
431
455
#ifdef _WIN32
432
456
sock -> sd = INVALID_SOCKET ;
@@ -436,6 +460,8 @@ mongoc_socket_close (mongoc_socket_t *sock) /* IN */
436
460
RETURN (0 );
437
461
}
438
462
463
+ _mongoc_socket_capture_errno (sock );
464
+
439
465
RETURN (-1 );
440
466
}
441
467
@@ -477,13 +503,13 @@ mongoc_socket_connect (mongoc_socket_t *sock, /* IN */
477
503
478
504
ret = connect (sock -> sd , addr , addrlen );
479
505
480
- _mongoc_socket_capture_errno (sock );
481
-
482
506
#ifdef _WIN32
483
507
if (ret == SOCKET_ERROR ) {
484
508
#else
485
509
if (ret == -1 ) {
486
510
#endif
511
+ _mongoc_socket_capture_errno (sock );
512
+
487
513
failed = true;
488
514
try_again = _mongoc_socket_errno_is_again (sock );
489
515
}
@@ -692,7 +718,9 @@ mongoc_socket_recv (mongoc_socket_t *sock, /* IN */
692
718
ret = recv (sock -> sd , buf , buflen , flags );
693
719
failed = (ret == -1 );
694
720
#endif
695
- _mongoc_socket_capture_errno (sock );
721
+ if (failed ) {
722
+ _mongoc_socket_capture_errno (sock );
723
+ }
696
724
try_again = (failed && _mongoc_socket_errno_is_again (sock ));
697
725
698
726
if (failed && try_again ) {
@@ -707,7 +735,7 @@ mongoc_socket_recv (mongoc_socket_t *sock, /* IN */
707
735
708
736
DUMP_BYTES (recvbuf , (uint8_t * )buf , ret );
709
737
710
- mongoc_counter_streams_ingress_add (ret > 0 ? ret : 0 );
738
+ mongoc_counter_streams_ingress_add (ret );
711
739
712
740
RETURN (ret );
713
741
}
@@ -795,9 +823,8 @@ mongoc_socket_send (mongoc_socket_t *sock, /* IN */
795
823
* _mongoc_socket_try_sendv_slow --
796
824
*
797
825
* A slow variant of _mongoc_socket_try_sendv() that sends each
798
- * iovec entry one by one. This can happen if we hit EMSGSIZE on
799
- * with sendmsg() on various POSIX systems (such as Solaris), or
800
- * on WinXP.
826
+ * iovec entry one by one. This can happen if we hit EMSGSIZE
827
+ * with sendmsg() on various POSIX systems.
801
828
*
802
829
* Returns:
803
830
* the number of bytes sent or -1 and errno is set.
@@ -825,12 +852,13 @@ _mongoc_socket_try_sendv_slow (mongoc_socket_t *sock, /* IN */
825
852
826
853
for (i = 0 ; i < iovcnt ; i ++ ) {
827
854
wrote = send (sock -> sd , iov [i ].iov_base , iov [i ].iov_len , 0 );
828
- _mongoc_socket_capture_errno (sock );
829
855
#ifdef _WIN32
830
856
if (wrote == SOCKET_ERROR ) {
831
857
#else
832
858
if (wrote == -1 ) {
833
859
#endif
860
+ _mongoc_socket_capture_errno (sock );
861
+
834
862
if (!_mongoc_socket_errno_is_again (sock )) {
835
863
RETURN (-1 );
836
864
}
@@ -913,7 +941,7 @@ _mongoc_socket_try_sendv (mongoc_socket_t *sock, /* IN */
913
941
#else
914
942
if ((ret == -1 ) && (errno == EMSGSIZE )) {
915
943
#endif
916
- _mongoc_socket_try_sendv_slow (sock , iov , iovcnt );
944
+ RETURN ( _mongoc_socket_try_sendv_slow (sock , iov , iovcnt ) );
917
945
}
918
946
919
947
_mongoc_socket_capture_errno (sock );
@@ -947,20 +975,24 @@ _mongoc_socket_try_sendv (mongoc_socket_t *sock, /* IN */
947
975
948
976
ssize_t
949
977
mongoc_socket_sendv (mongoc_socket_t * sock , /* IN */
950
- mongoc_iovec_t * iov , /* IN */
978
+ mongoc_iovec_t * in_iov , /* IN */
951
979
size_t iovcnt , /* IN */
952
980
int64_t expire_at ) /* IN */
953
981
{
954
982
ssize_t ret = 0 ;
955
983
ssize_t sent ;
956
984
size_t cur = 0 ;
985
+ mongoc_iovec_t * iov ;
957
986
958
987
ENTRY ;
959
988
960
989
bson_return_val_if_fail (sock , -1 );
961
- bson_return_val_if_fail (iov , -1 );
990
+ bson_return_val_if_fail (in_iov , -1 );
962
991
bson_return_val_if_fail (iovcnt , -1 );
963
992
993
+ iov = bson_malloc (sizeof (* iov ) * iovcnt );
994
+ memcpy (iov , in_iov , sizeof (* iov ) * iovcnt );
995
+
964
996
for (;;) {
965
997
sent = _mongoc_socket_try_sendv (sock , & iov [cur ], iovcnt - cur );
966
998
@@ -971,7 +1003,8 @@ mongoc_socket_sendv (mongoc_socket_t *sock, /* IN */
971
1003
*/
972
1004
if (sent == -1 ) {
973
1005
if (!_mongoc_socket_errno_is_again (sock )) {
974
- RETURN (ret ? ret : -1 );
1006
+ ret = -1 ;
1007
+ goto CLEANUP ;
975
1008
}
976
1009
}
977
1010
@@ -1007,29 +1040,20 @@ mongoc_socket_sendv (mongoc_socket_t *sock, /* IN */
1007
1040
BSON_ASSERT (iovcnt - cur );
1008
1041
BSON_ASSERT (iov [cur ].iov_len );
1009
1042
} else if (OPERATION_EXPIRED (expire_at )) {
1010
- #ifdef _WIN32
1011
- errno = WSAETIMEDOUT ;
1012
- #else
1013
- errno = ETIMEDOUT ;
1014
- #endif
1015
- RETURN (ret ? ret : -1 );
1043
+ goto CLEANUP ;
1016
1044
}
1017
1045
1018
1046
/*
1019
1047
* Block on poll() until our desired condition is met.
1020
1048
*/
1021
1049
if (!_mongoc_socket_wait (sock -> sd , POLLOUT , expire_at )) {
1022
- if (ret == 0 ){
1023
- #ifdef _WIN32
1024
- errno = WSAETIMEDOUT ;
1025
- #else
1026
- errno = ETIMEDOUT ;
1027
- #endif
1028
- }
1029
- RETURN (ret ? ret : -1 );
1050
+ goto CLEANUP ;
1030
1051
}
1031
1052
}
1032
1053
1054
+ CLEANUP :
1055
+ bson_free (iov );
1056
+
1033
1057
RETURN (ret );
1034
1058
}
1035
1059
0 commit comments