ObexTransportAgent: fixing an obex event leak for SyncML server case

ObexEvent which wraps an underlying OBEX event source is expected to
be released during ObexTransportAgent class destructing or during
wait() where we copied it to the local stack.

The assumption was: wait() is called after each send(). This is not
correct for SyncML server case. Therefore later shutdown() sets up a
new ObexEvent and overwrites the old one without releasing the resource.
This may also occurs if user calls send(), send() without calling wait()
in between (Rarely, though).

The solution is to check explictly whether m_obexEvent already wraps a resource
before assigning a new value to it.
This commit is contained in:
Chen Congwu 2009-11-26 15:13:08 +08:00 committed by Patrick Ohly
parent 1f00c71eab
commit fe124636b3
2 changed files with 21 additions and 2 deletions

View file

@ -254,6 +254,16 @@ void ObexTransportAgent::shutdown() {
OBEX_ObjectAddHeader (m_handle->get(), disconnect, OBEX_HDR_CONNECTION, header, sizeof
(m_connectId), OBEX_FL_FIT_ONE_PACKET);
/*
* This is a must check when working with SyncML server case:
* It will not call wait() for the last send(), which caused the
* event source set up during that send() has no chance to be removed
* until here.
* */
if (m_obexEvent) {
m_obexEvent.set(NULL);
}
//reset up obex fd soruce
guint obexSource = g_io_add_watch (m_channel->get(), (GIOCondition) (G_IO_IN|G_IO_OUT|G_IO_HUP|G_IO_ERR|G_IO_NVAL), obex_fd_source_cb, static_cast<void *> (this));
cxxptr<ObexEvent> obexEventSource (new ObexEvent (obexSource));
@ -299,6 +309,14 @@ void ObexTransportAgent::send(const char *data, size_t len) {
header.bs = reinterpret_cast <const uint8_t *> (data);
OBEX_ObjectAddHeader (m_handle->get(), put, OBEX_HDR_BODY, header, len, 0);
/*
* This is a safe check, the problem is:
* If application called send() and without calling wait() it calls send()
* again, this will leading to a event leak.
* */
if (m_obexEvent) {
m_obexEvent.set(NULL);
}
//reset up the OBEX fd source
guint obexSource = g_io_add_watch (channel->get(), (GIOCondition) (G_IO_IN|G_IO_OUT|G_IO_HUP|G_IO_ERR|G_IO_NVAL), obex_fd_source_cb, static_cast<void *> (this));
cxxptr<ObexEvent> obexEventSource (new ObexEvent (obexSource));

View file

@ -59,8 +59,9 @@ class ObexEvent {
guint event;
public:
ObexEvent() {event = 0;}
ObexEvent (guint e) {event = e;}
~ObexEvent () {if (event) {g_source_remove (event);}}
ObexEvent (guint e) {event = e; SE_LOG_DEBUG (NULL, NULL, "ObexTransportAgent: creating obex event %d", e);}
~ObexEvent () {if (event) {g_source_remove (event);}
SE_LOG_DEBUG (NULL, NULL, "ObexTransportAgent: removing obex event %d", event);}
guint get() {return event;}
};