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:
parent
1f00c71eab
commit
fe124636b3
2 changed files with 21 additions and 2 deletions
|
@ -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));
|
||||
|
|
|
@ -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;}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue