Browse Source

fix leaks, close handling and things.

1.0.0
Georg Hopp 11 years ago
parent
commit
f79801180c
  1. 8
      src/cep_buffer_read.c
  2. 1
      src/comm_manager.c
  3. 14
      src/connection.c
  4. 24
      src/io_handler.c
  5. 17
      src/protocol_handler.c
  6. 68
      testers/leak.log
  7. 65
      testers/testserver.c

8
src/cep_buffer_read.c

@ -30,13 +30,11 @@ TR_cepBufferRead(TR_CommEndPoint this)
{ {
TR_RemoteData data = TR_socketRecv(this->transport, this->read_chunk_size); TR_RemoteData data = TR_socketRecv(this->transport, this->read_chunk_size);
if (! data) return FALSE;
if (! data) return -1; // ment to trigger a close
if (data == (void*)-1) return -2; // remote close... shutdown
if (data == TR_emptyRemoteData) return FALSE;
while (data) {
TR_cepAppendReadData(this, data); TR_cepAppendReadData(this, data);
data = TR_socketRecv(this->transport, this->read_chunk_size);
}
return TRUE; return TRUE;
} }

1
src/comm_manager.c

@ -55,6 +55,7 @@ commManagerDtor(void * _this)
for (i = 0; i < this->n_endpoints; i++) { for (i = 0; i < this->n_endpoints; i++) {
TR_delete(this->endpoints[i]); TR_delete(this->endpoints[i]);
} }
TR_MEM_FREE(this->endpoints);
} }
static static

14
src/connection.c

@ -62,15 +62,17 @@ connectionNextMessage(void * _this)
TR_Connection this = _this; TR_Connection this = _this;
TR_CommEndPoint comm = _this; TR_CommEndPoint comm = _this;
TR_RemoteData data = TR_queueGet(comm->read_buffer); TR_RemoteData data = TR_queueGet(comm->read_buffer);
TR_ProtoMessage ret_message = NULL;
size_t end; size_t end;
if (data && (! this->current_message || this->current_message->ready))
if (NULL == data) return ret_message;
if (! this->current_message || this->current_message->ready)
{ {
this->current_message = this->current_message =
TR_protoCreateMessage(comm->protocol, data->remote); TR_protoCreateMessage(comm->protocol, data->remote);
} }
while (NULL != data) {
end = TR_protoParse(comm->protocol, this->current_message, data); end = TR_protoParse(comm->protocol, this->current_message, data);
if (end != ((TR_SizedData)data)->size) { if (end != ((TR_SizedData)data)->size) {
@ -102,13 +104,11 @@ connectionNextMessage(void * _this)
} }
if (this->current_message->ready) { if (this->current_message->ready) {
return this->current_message;
}
data = TR_queueGet(comm->read_buffer);
ret_message = this->current_message;
this->current_message = NULL;
} }
return NULL;
return ret_message;
} }
static static

24
src/io_handler.c

@ -46,12 +46,34 @@ ioHandlerRead(void * _this, TR_Event event)
{ {
TR_CommEndPoint endpoint = (TR_CommEndPoint)event->subject; TR_CommEndPoint endpoint = (TR_CommEndPoint)event->subject;
if (TR_cepBufferRead(endpoint)) {
switch (TR_cepBufferRead(endpoint)) {
default:
case FALSE:
break;
case -1:
TR_eventHandlerIssueEvent(
(TR_EventHandler)_this,
event->subject,
TR_CEP_EVENT_CLOSE,
NULL);
break;
case -2:
TR_eventHandlerIssueEvent(
(TR_EventHandler)_this,
event->subject,
TR_CEP_EVENT_SHUT_READ,
NULL);
break;
case TRUE:
TR_eventHandlerIssueEvent( TR_eventHandlerIssueEvent(
(TR_EventHandler)_this, (TR_EventHandler)_this,
event->subject, event->subject,
TR_CEP_EVENT_NEW_DATA, TR_CEP_EVENT_NEW_DATA,
NULL); NULL);
break;
} }
return TRUE; return TRUE;

17
src/protocol_handler.c

@ -53,7 +53,7 @@ protocolHandlerParse(void * _this, TR_Event event)
TR_CommEndPoint endpoint = (TR_CommEndPoint)event->subject; TR_CommEndPoint endpoint = (TR_CommEndPoint)event->subject;
TR_ProtoMessage message = TR_cepNextMessage(endpoint); TR_ProtoMessage message = TR_cepNextMessage(endpoint);
while (message) {
if (message) {
TR_eventHandlerIssueEvent( TR_eventHandlerIssueEvent(
(TR_EventHandler)_this, (TR_EventHandler)_this,
event->subject, event->subject,
@ -65,8 +65,6 @@ protocolHandlerParse(void * _this, TR_Event event)
// in the python code... // in the python code...
TR_cepSetClose(endpoint); TR_cepSetClose(endpoint);
} }
message = TR_cepNextMessage(endpoint);
} }
return TRUE; return TRUE;
@ -79,18 +77,19 @@ protocolHandlerCompose(void * _this, TR_Event event)
TR_CommEndPoint endpoint = (TR_CommEndPoint)event->subject; TR_CommEndPoint endpoint = (TR_CommEndPoint)event->subject;
TR_ProtoMessage message = (TR_ProtoMessage)event->data; TR_ProtoMessage message = (TR_ProtoMessage)event->data;
if (message->close) {
// also check that we are a response. Well this is how it is done
// in the python code...
TR_cepSetClose(endpoint);
}
if (TR_cepCompose(endpoint, message)) { if (TR_cepCompose(endpoint, message)) {
TR_eventHandlerIssueEvent( TR_eventHandlerIssueEvent(
(TR_EventHandler)_this, (TR_EventHandler)_this,
event->subject, event->subject,
TR_CEP_EVENT_WRITE_READY, TR_CEP_EVENT_WRITE_READY,
NULL); NULL);
}
if (message->close) {
// also check that we are a response. Well this is how it is done
// in the python code...
TR_cepSetClose(endpoint);
TR_delete(message);
} }
return TRUE; return TRUE;

68
testers/leak.log

@ -0,0 +1,68 @@
==25008== Memcheck, a memory error detector
==25008== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==25008== Using Valgrind-3.9.0 and LibVEX; rerun with -h for copyright info
==25008== Command: ./testserver
==25008==
==25008== Conditional jump or move depends on uninitialised value(s)
==25008== at 0x4017A74: index (strchr.S:77)
==25008== by 0x400743D: expand_dynamic_string_token (dl-load.c:425)
==25008== by 0x400802D: _dl_map_object (dl-load.c:2302)
==25008== by 0x400138D: map_doit (rtld.c:626)
==25008== by 0x400E993: _dl_catch_error (dl-error.c:187)
==25008== by 0x4000B30: do_preload (rtld.c:815)
==25008== by 0x4004122: dl_main (rtld.c:1632)
==25008== by 0x401533B: _dl_sysdep_start (dl-sysdep.c:249)
==25008== by 0x4004A4C: _dl_start (rtld.c:331)
==25008== by 0x40011A7: ??? (in /lib64/ld-2.19.so)
==25008==
==25008==
==25008== HEAP SUMMARY:
==25008== in use at exit: 1,024 bytes in 4 blocks
==25008== total heap usage: 12,272 allocs, 12,268 frees, 1,601,216 bytes allocated
==25008==
==25008== 256 bytes in 1 blocks are definitely lost in loss record 1 of 4
==25008== at 0x4C28730: malloc (vg_replace_malloc.c:291)
==25008== by 0x4E3497C: newElement (memory.c:82)
==25008== by 0x4E34B19: TR_malloc (memory.c:442)
==25008== by 0x4E34B50: TR_calloc (memory.c:460)
==25008== by 0x4E35144: TR_classNewv (i_class.c:55)
==25008== by 0x4E3532E: TR_classNew (i_class.c:81)
==25008== by 0x4018DA: main (testserver.c:123)
==25008==
==25008== 256 bytes in 1 blocks are definitely lost in loss record 2 of 4
==25008== at 0x4C28730: malloc (vg_replace_malloc.c:291)
==25008== by 0x4E3497C: newElement (memory.c:82)
==25008== by 0x4E34B19: TR_malloc (memory.c:442)
==25008== by 0x4E34B50: TR_calloc (memory.c:460)
==25008== by 0x4E35144: TR_classNewv (i_class.c:55)
==25008== by 0x4E3532E: TR_classNew (i_class.c:81)
==25008== by 0x4018F2: main (testserver.c:124)
==25008==
==25008== 256 bytes in 1 blocks are definitely lost in loss record 3 of 4
==25008== at 0x4C28730: malloc (vg_replace_malloc.c:291)
==25008== by 0x4E3497C: newElement (memory.c:82)
==25008== by 0x4E34B19: TR_malloc (memory.c:442)
==25008== by 0x4E34B50: TR_calloc (memory.c:460)
==25008== by 0x4E35144: TR_classNewv (i_class.c:55)
==25008== by 0x4E3532E: TR_classNew (i_class.c:81)
==25008== by 0x40190A: main (testserver.c:125)
==25008==
==25008== 256 bytes in 1 blocks are definitely lost in loss record 4 of 4
==25008== at 0x4C28730: malloc (vg_replace_malloc.c:291)
==25008== by 0x4E3497C: newElement (memory.c:82)
==25008== by 0x4E34B19: TR_malloc (memory.c:442)
==25008== by 0x4E34B50: TR_calloc (memory.c:460)
==25008== by 0x4E35144: TR_classNewv (i_class.c:55)
==25008== by 0x4E3532E: TR_classNew (i_class.c:81)
==25008== by 0x401920: main (testserver.c:126)
==25008==
==25008== LEAK SUMMARY:
==25008== definitely lost: 1,024 bytes in 4 blocks
==25008== indirectly lost: 0 bytes in 0 blocks
==25008== possibly lost: 0 bytes in 0 blocks
==25008== still reachable: 0 bytes in 0 blocks
==25008== suppressed: 0 bytes in 0 blocks
==25008==
==25008== For counts of detected and suppressed errors, rerun with: -v
==25008== Use --track-origins=yes to see where uninitialised values come from
==25008== ERROR SUMMARY: 5 errors from 5 contexts (suppressed: 0 from 0)

65
testers/testserver.c

@ -1,4 +1,5 @@
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include "trbase.h" #include "trbase.h"
#include "trcomm.h" #include "trcomm.h"
@ -6,6 +7,7 @@
TR_CLASS(TestHandler) { TR_CLASS(TestHandler) {
TR_EXTENDS(TR_EventHandler); TR_EXTENDS(TR_EventHandler);
unsigned long long handled;
}; };
TR_INSTANCE_INIT(TestHandler); TR_INSTANCE_INIT(TestHandler);
TR_CLASSVARS_DECL(TestHandler) { TR_CLASSVARS_DECL(TestHandler) {
@ -16,7 +18,8 @@ static
int int
testHandlerHeartbeat(TR_EventHandler this, TR_Event event) testHandlerHeartbeat(TR_EventHandler this, TR_Event event)
{ {
puts("heartbeat");
printf("handled: %llu/s\n", ((TestHandler)this)->handled);
((TestHandler)this)->handled = 0;
return FALSE; return FALSE;
} }
@ -24,7 +27,26 @@ static
int int
testHandlerNewMessage(TR_EventHandler this, TR_Event event) testHandlerNewMessage(TR_EventHandler this, TR_Event event)
{ {
puts("new message");
TR_ProtoMessageRaw msg = event->data;
TR_SizedData data = (TR_SizedData)msg->data;
char buf[data->size + 1];
int i;
((TestHandler)this)->handled++;
memcpy(buf, data->data, data->size);
buf[data->size] = 0;
for (i = 0; buf[i]; i++) {
if (! isprint(buf[i])) buf[i] = '.';
}
// printf("echo message: %s(%zd)\n", buf, data->size);
TR_eventHandlerIssueEvent(
(TR_EventHandler)this,
event->subject,
TR_CEP_EVENT_SEND_MSG,
event->data);
return FALSE; return FALSE;
} }
@ -49,6 +71,8 @@ int
testHandlerCtor(void * _this, va_list * params) testHandlerCtor(void * _this, va_list * params)
{ {
TR_PARENTCALL(TestHandler, _this, TR_Class, ctor, params); TR_PARENTCALL(TestHandler, _this, TR_Class, ctor, params);
((TestHandler)_this)->handled = 0;
return 0; return 0;
} }
@ -102,6 +126,10 @@ main (int argc, char * argv[])
{ {
TR_CommManager cmgr = (TR_CommManager)TR_new(TR_CommManagerPoll); TR_CommManager cmgr = (TR_CommManager)TR_new(TR_CommManagerPoll);
TR_EventDispatcher dispatcher = TR_new(TR_EventDispatcher); TR_EventDispatcher dispatcher = TR_new(TR_EventDispatcher);
TR_Connector connector = TR_new(TR_Connector);
TR_IoHandler io_handler = TR_new(TR_IoHandler);
TR_ProtocolHandler protocol_handler = TR_new(TR_ProtocolHandler);
TestHandler test_handler = TR_new(TestHandler);
TR_ConnEntryPoint ep; TR_ConnEntryPoint ep;
TR_TcpSocket ep_sock; TR_TcpSocket ep_sock;
TR_Protocol protocol; TR_Protocol protocol;
@ -109,14 +137,14 @@ main (int argc, char * argv[])
TR_logger = TR_INSTANCE_CAST(TR_Logger, mylogger); TR_logger = TR_INSTANCE_CAST(TR_Logger, mylogger);
TR_eventDispatcherRegisterHandler(dispatcher, (TR_EventHandler)cmgr); TR_eventDispatcherRegisterHandler(dispatcher, (TR_EventHandler)cmgr);
TR_eventDispatcherRegisterHandler(dispatcher,
(TR_EventHandler)TR_new(TR_Connector));
TR_eventDispatcherRegisterHandler(dispatcher,
(TR_EventHandler)TR_new(TR_IoHandler));
TR_eventDispatcherRegisterHandler(dispatcher,
(TR_EventHandler)TR_new(TR_ProtocolHandler));
TR_eventDispatcherRegisterHandler(dispatcher,
(TR_EventHandler)TR_new(TestHandler));
TR_eventDispatcherRegisterHandler(dispatcher, (TR_EventHandler)connector);
TR_eventDispatcherRegisterHandler(dispatcher, (TR_EventHandler)io_handler);
TR_eventDispatcherRegisterHandler(
dispatcher,
(TR_EventHandler)protocol_handler);
TR_eventDispatcherRegisterHandler(
dispatcher,
(TR_EventHandler)test_handler);
protocol = TR_new(TR_ProtocolRaw); protocol = TR_new(TR_ProtocolRaw);
ep_sock = TR_new(TR_TcpSocket, TR_logger, "0.0.0.0", 5678, 0); ep_sock = TR_new(TR_TcpSocket, TR_logger, "0.0.0.0", 5678, 0);
@ -126,10 +154,25 @@ main (int argc, char * argv[])
TR_eventDispatcherSetHeartbeat(dispatcher, 1000); TR_eventDispatcherSetHeartbeat(dispatcher, 1000);
TR_eventDispatcherStart(dispatcher); TR_eventDispatcherStart(dispatcher);
TR_eventHandlerClassCleanup(TestHandler);
puts("cleanup...");
TR_delete(cmgr); TR_delete(cmgr);
TR_delete(dispatcher); TR_delete(dispatcher);
TR_delete(connector);
TR_delete(io_handler);
TR_delete(protocol_handler);
TR_delete(test_handler);
TR_delete(protocol);
//TR_delete(ep);
TR_eventHandlerClassCleanup(TestHandler);
TR_eventHandlerClassCleanup(TR_ProtocolHandler);
TR_eventHandlerClassCleanup(TR_IoHandler);
TR_eventHandlerClassCleanup(TR_Connector);
TR_eventHandlerClassCleanup(TR_CommManagerPoll);
TR_cleanup();
return 0; return 0;
} }

Loading…
Cancel
Save