aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMicael Karlberg <[email protected]>2018-10-16 15:53:37 +0200
committerMicael Karlberg <[email protected]>2018-10-16 15:53:37 +0200
commit043624804888dc021a75b01c0a3d8c1c0a1fde23 (patch)
treed143e2561adf5e87335329565ad05026efb15dbd
parentf2481d58a2fb64b8f3c7cbb26e09cb17c04726e0 (diff)
downloadotp-043624804888dc021a75b01c0a3d8c1c0a1fde23.tar.gz
otp-043624804888dc021a75b01c0a3d8c1c0a1fde23.tar.bz2
otp-043624804888dc021a75b01c0a3d8c1c0a1fde23.zip
[socket-nif] Recv handling of closing sockets
Fixed more issues regarding closing sockets. Specifically with respect to recv calls. Also, added demonitor for all *current* processes. Also fixed a buffer overflow problem when writing an warning message (the timestamp buffer was not large enough). OTP-14831
-rw-r--r--erts/emulator/nifs/common/socket_nif.c61
-rw-r--r--erts/emulator/nifs/common/socket_util.c2
2 files changed, 51 insertions, 12 deletions
diff --git a/erts/emulator/nifs/common/socket_nif.c b/erts/emulator/nifs/common/socket_nif.c
index f09f618653..3ec19c5a60 100644
--- a/erts/emulator/nifs/common/socket_nif.c
+++ b/erts/emulator/nifs/common/socket_nif.c
@@ -4776,17 +4776,23 @@ ERL_NIF_TERM nclose(ErlNifEnv* env,
if (selectRes & ERL_NIF_SELECT_STOP_CALLED) {
/* Prep done - inform the caller it can finalize (close) directly */
SSDBG( descP,
- ("SOCKET", "nclose -> [%d] stop called\r\n", descP->sock) );
+ ("SOCKET", "nclose -> [%d] stop was called\r\n", descP->sock) );
dec_socket(domain, type, protocol);
reply = esock_atom_ok;
} else if (selectRes & ERL_NIF_SELECT_STOP_SCHEDULED) {
/* The stop callback function has been *scheduled* which means that we
* have to wait for it to complete. */
SSDBG( descP,
- ("SOCKET", "nclose -> [%d] stop scheduled\r\n", descP->sock) );
+ ("SOCKET", "nclose -> [%d] stop was scheduled\r\n",
+ descP->sock) );
dec_socket(domain, type, protocol); // SHALL WE DO THIS AT finalize?
reply = esock_make_ok2(env, descP->closeRef);
} else {
+
+ SSDBG( descP,
+ ("SOCKET", "nclose -> [%d] stop failed: %d\r\n",
+ descP->sock, selectRes) );
+
/* <KOLLA>
*
* WE SHOULD REALLY HAVE A WAY TO CLOBBER THE SOCKET,
@@ -4796,6 +4802,7 @@ ERL_NIF_TERM nclose(ErlNifEnv* env,
*
* </KOLLA>
*/
+
reason = MKT2(env, atom_select, MKI(env, selectRes));
reply = esock_make_error(env, reason);
}
@@ -12000,6 +12007,9 @@ ERL_NIF_TERM recv_check_result(ErlNifEnv* env,
SSDBG( descP, ("SOCKET",
"recv_check_result -> [%d] eagain\r\n", toRead) );
+ if ((xres = recv_init_current_reader(env, descP, recvRef)) != NULL)
+ return esock_make_error_str(env, xres);
+
SELECT(env, descP->sock, (ERL_NIF_SELECT_READ),
descP, NULL, recvRef);
@@ -15005,6 +15015,7 @@ static
void socket_stop(ErlNifEnv* env, void* obj, int fd, int is_direct_call)
{
SocketDescriptor* descP = (SocketDescriptor*) obj;
+ int dres;
SSDBG( descP,
("SOCKET", "socket_stop -> entry when"
@@ -15033,15 +15044,24 @@ void socket_stop(ErlNifEnv* env, void* obj, int fd, int is_direct_call)
*/
SSDBG( descP,
("SOCKET",
- "socket_stop -> demonitor (maybe) controlling process\r\n") );
- DEMONP(env, descP, &descP->ctrlMon);
+ "socket_stop -> demonitor (maybe) controlling process (%T)\r\n",
+ descP->ctrlPid) );
+ dres = DEMONP(env, descP, &descP->ctrlMon);
+ SSDBG( descP, ("SOCKET", "socket_stop -> demonitor result: %d\r\n", dres) );
+
if (descP->currentWriterP != NULL) {
/* We have a (current) writer and *may* therefor also have
* writers waiting.
*/
- SSDBG( descP, ("SOCKET", "socket_stop -> handle writer(s)\r\n") );
+ SSDBG( descP,
+ ("SOCKET",
+ "socket_stop -> demonitor (maybe) current writer: %T, %T\r\n",
+ descP->currentWriter.pid, descP->currentWriter.ref) );
+ DEMONP(env, descP, &descP->currentWriter.mon);
+
+ SSDBG( descP, ("SOCKET", "socket_stop -> handle current writer\r\n") );
if (!compare_pids(env,
&descP->closerPid,
&descP->currentWriter.pid) &&
@@ -15059,6 +15079,7 @@ void socket_stop(ErlNifEnv* env, void* obj, int fd, int is_direct_call)
}
/* And also deal with the waiting writers (in the same way) */
+ SSDBG( descP, ("SOCKET", "socket_stop -> handle waiting writer(s)\r\n") );
inform_waiting_procs(env, descP, &descP->writersQ, TRUE, atom_closed);
}
@@ -15068,7 +15089,13 @@ void socket_stop(ErlNifEnv* env, void* obj, int fd, int is_direct_call)
* readers waiting.
*/
- SSDBG( descP, ("SOCKET", "socket_stop -> handle reader(s)\r\n") );
+ SSDBG( descP,
+ ("SOCKET",
+ "socket_stop -> demonitor (maybe) current reader: %T, %T\r\n",
+ descP->currentReader.pid, descP->currentReader.ref) );
+ DEMONP(env, descP, &descP->currentReader.mon);
+
+ SSDBG( descP, ("SOCKET", "socket_stop -> handle current reader\r\n") );
if (!compare_pids(env,
&descP->closerPid,
&descP->currentReader.pid) &&
@@ -15086,6 +15113,7 @@ void socket_stop(ErlNifEnv* env, void* obj, int fd, int is_direct_call)
}
/* And also deal with the waiting readers (in the same way) */
+ SSDBG( descP, ("SOCKET", "socket_stop -> handle waiting reader(s)\r\n") );
inform_waiting_procs(env, descP, &descP->readersQ, TRUE, atom_closed);
}
@@ -15094,7 +15122,13 @@ void socket_stop(ErlNifEnv* env, void* obj, int fd, int is_direct_call)
* acceptors waiting.
*/
- SSDBG( descP, ("SOCKET", "socket_stop -> handle acceptor(s)\r\n") );
+ SSDBG( descP,
+ ("SOCKET",
+ "socket_stop -> demonitor (maybe) current acceptor: %T, %T\r\n",
+ descP->currentAcceptor.pid, descP->currentAcceptor.ref) );
+ DEMONP(env, descP, &descP->currentAcceptor.mon);
+
+ SSDBG( descP, ("SOCKET", "socket_stop -> handle current acceptor\r\n") );
if (!compare_pids(env,
&descP->closerPid,
&descP->currentAcceptor.pid) &&
@@ -15112,6 +15146,7 @@ void socket_stop(ErlNifEnv* env, void* obj, int fd, int is_direct_call)
}
/* And also deal with the waiting acceptors (in the same way) */
+ SSDBG( descP, ("SOCKET", "socket_stop -> handle waiting acceptor(s)\r\n") );
inform_waiting_procs(env, descP, &descP->acceptorsQ, TRUE, atom_closed);
}
@@ -15237,9 +15272,13 @@ void socket_down(ErlNifEnv* env,
SocketDescriptor* descP = (SocketDescriptor*) obj;
SSDBG( descP, ("SOCKET", "socket_down -> entry with"
- "\r\n sock: %d"
- "\r\n pid: %T"
- "\r\n", descP->sock, *pid) );
+ "\r\n sock: %d"
+ "\r\n pid: %T"
+ "\r\n Closed: %s"
+ "\r\n Closing: %s"
+ "\r\n",
+ descP->sock, *pid,
+ B2S(IS_CLOSED(descP)), B2S(IS_CLOSING(descP))) );
if (compare_pids(env, &descP->ctrlPid, pid)) {
@@ -15249,7 +15288,7 @@ void socket_down(ErlNifEnv* env,
* we leave it to the stop callback function.
*/
- SSDBG( descP, ("SOCKET", "socket_down -> controlling process term\r\n") );
+ SSDBG( descP, ("SOCKET", "socket_down -> controlling process exit\r\n") );
descP->state = SOCKET_STATE_CLOSING;
descP->closeLocal = TRUE;
diff --git a/erts/emulator/nifs/common/socket_util.c b/erts/emulator/nifs/common/socket_util.c
index ff50fd2384..766d3724c1 100644
--- a/erts/emulator/nifs/common/socket_util.c
+++ b/erts/emulator/nifs/common/socket_util.c
@@ -1506,7 +1506,7 @@ void esock_warning_msg( const char* format, ... )
{
va_list args;
char f[512 + sizeof(format)]; // This has to suffice...
- char stamp[32];
+ char stamp[64]; // Just in case...
struct timespec ts;
int res;