diff options
author | Kristen Carlson Accardi <kristen@linux.intel.com> | 2010-03-24 21:41:54 -0700 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2010-03-25 06:50:10 -0700 |
commit | f720a27a1f41c9fe8f079df5252f5535ad6338f4 (patch) | |
tree | aec6ed7ef83289516201e4f56cb01d55fc9c3c7a | |
parent | 06ae2b2c9879cfdc10d38cc4fbd83e32f1c79986 (diff) | |
download | ofono-f720a27a1f41c9fe8f079df5252f5535ad6338f4.tar.bz2 |
separate memory cleanup from PPP shutdown
don't free memory at PPP shutdown, because we need to be able to
send terminate traffic. Free memory when we have reached the
PPP_DEAD phase instead.
-rw-r--r-- | gatchat/gatppp.c | 25 | ||||
-rw-r--r-- | gatchat/ppp.c | 23 |
2 files changed, 29 insertions, 19 deletions
diff --git a/gatchat/gatppp.c b/gatchat/gatppp.c index 68c4dd1e..8f196364 100644 --- a/gatchat/gatppp.c +++ b/gatchat/gatppp.c @@ -66,22 +66,8 @@ void g_at_ppp_set_disconnect_function(GAtPPP *ppp, void g_at_ppp_shutdown(GAtPPP *ppp) { - /* close the ppp */ + /* close the ppp link */ ppp_close(ppp); - - /* clean up all the queues */ - g_queue_free(ppp->event_queue); - g_queue_free(ppp->recv_queue); - - /* cleanup modem channel */ - g_source_remove(ppp->modem_watch); - g_io_channel_unref(ppp->modem); - - /* remove lcp */ - lcp_free(ppp->lcp); - - /* remove auth */ - auth_free(ppp->auth); } void g_at_ppp_ref(GAtPPP *ppp) @@ -91,10 +77,13 @@ void g_at_ppp_ref(GAtPPP *ppp) void g_at_ppp_unref(GAtPPP *ppp) { - if (g_atomic_int_dec_and_test(&ppp->ref_count)) { + if (g_atomic_int_dec_and_test(&ppp->ref_count)) g_at_ppp_shutdown(ppp); - g_free(ppp); - } + + /* + * we can't free the link yet, because we need to terminate + * the link first. + */ } GAtPPP *g_at_ppp_new(GIOChannel *modem) diff --git a/gatchat/ppp.c b/gatchat/ppp.c index f3bfba7c..d771c3fb 100644 --- a/gatchat/ppp.c +++ b/gatchat/ppp.c @@ -372,7 +372,28 @@ static void ppp_authenticate(GAtPPP *ppp) static void ppp_dead(GAtPPP *ppp) { - /* re-initialize everything */ + /* notify interested parties */ + if (ppp->disconnect_cb) + ppp->disconnect_cb(ppp, ppp->disconnect_data); + + if (g_atomic_int_get(&ppp->ref_count)) + return; + + /* clean up all the queues */ + g_queue_free(ppp->event_queue); + g_queue_free(ppp->recv_queue); + + /* cleanup modem channel */ + g_source_remove(ppp->modem_watch); + g_io_channel_unref(ppp->modem); + + /* remove lcp */ + lcp_free(ppp->lcp); + + /* remove auth */ + auth_free(ppp->auth); + + g_free(ppp); } static void ppp_network(GAtPPP *ppp) |