From 5eb5a8dea64cad10634930a49e82148a6265e472 Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Mon, 24 Oct 2016 08:40:46 -0700 Subject: 3581 Fix CI. 3 different memory leaks in the socket internals. The hard one was recognizing the need for `receive-from-client-socket-and-close`. --- 091socket.cc | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) (limited to '091socket.cc') diff --git a/091socket.cc b/091socket.cc index ee76d3c6..180f2b27 100644 --- a/091socket.cc +++ b/091socket.cc @@ -50,6 +50,7 @@ case _OPEN_CLIENT_SOCKET: { break; } long long int result = reinterpret_cast(client); +//? cerr << "$open-client-socket: " << client->fd << " -> " << result << '\n'; products.at(0).push_back(static_cast(result)); break; } @@ -108,6 +109,7 @@ case _OPEN_SERVER_SOCKET: { break; } long long int result = reinterpret_cast(server); +//? cerr << "$open-server-socket: " << server->fd << " -> " << result << '\n'; products.at(0).push_back(static_cast(result)); break; } @@ -168,9 +170,11 @@ case _ACCEPT: { if (server) { socket_t* session = accept_session(server); long long int result = reinterpret_cast(session); +//? cerr << "$accept from " << server->fd << ": " << session->fd << " -> " << result << '\n'; products.at(0).push_back(static_cast(result)); } else { +//? cerr << "error in $accept from " << server->fd << '\n'; products.at(0).push_back(0); } break; @@ -230,6 +234,7 @@ case _READ_FROM_SOCKET: { products.resize(4); long long int x = static_cast(ingredients.at(0).at(0)); socket_t* socket = reinterpret_cast(x); +//? cerr << "$read-from-socket: polling " << socket->fd << '\n'; // 1. we'd like to simply read() from the socket // however read() on a socket never returns EOF, so we wouldn't know when to stop // 2. recv() can signal EOF, but it also signals "no data yet" in the beginning @@ -243,6 +248,7 @@ case _READ_FROM_SOCKET: { p.events = POLLIN | POLLHUP; int status = poll(&p, /*num pollfds*/1, /*timeout*/100/*ms*/); if (status == 0) { +//? cerr << "$read-from-socket: poll() timeout\n"; products.at(0).push_back(/*no data*/0); products.at(1).push_back(/*found*/false); products.at(2).push_back(/*eof*/false); @@ -260,15 +266,24 @@ case _READ_FROM_SOCKET: { } socket->polled = true; } +//? cerr << "reading from socket " << socket->fd << '\n'; int bytes = static_cast(ingredients.at(1).at(0)); char* contents = new char[bytes]; bzero(contents, bytes); + int error_code = 0; int bytes_read = recv(socket->fd, contents, bytes-/*terminal null*/1, MSG_DONTWAIT); + if (bytes_read < 0) error_code = errno; +//? cerr << "bytes read: " << bytes_read << '\n'; +//? if (error_code) { +//? ostringstream out; +//? out << "error in $read-from-socket " << socket->fd; +//? perror(out.str().c_str()); +//? } products.at(0).push_back(new_mu_text(contents)); products.at(1).push_back(/*found*/true); products.at(2).push_back(/*eof*/bytes_read <= 0); - products.at(3).push_back(/*error*/0); - delete contents; + products.at(3).push_back(error_code); + delete[] contents; break; } @@ -288,9 +303,11 @@ case _WRITE_TO_SOCKET: { case _WRITE_TO_SOCKET: { long long int x = static_cast(ingredients.at(0).at(0)); socket_t* session = reinterpret_cast(x); +//? cerr << "writing to socket " << session->fd << '\n'; // write just one character at a time to the session socket long long int y = static_cast(ingredients.at(1).at(0)); char c = static_cast(y); +//? cerr << " " << c << '\n'; if (write(session->fd, &c, 1) != 1) { raise << maybe(current_recipe_name()) << "failed to write to socket\n" << end(); exit(0); @@ -321,7 +338,9 @@ case _CLOSE_SOCKET: { case _CLOSE_SOCKET: { long long int x = static_cast(ingredients.at(0).at(0)); socket_t* socket = reinterpret_cast(x); +//? cerr << "closing " << socket->fd << '\n'; close(socket->fd); + delete socket; break; } -- cgit 1.4.1-2-gfad0