summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKristen Carlson Accardi <kristen@linux.intel.com>2010-03-24 21:41:54 -0700
committerMarcel Holtmann <marcel@holtmann.org>2010-03-25 06:50:10 -0700
commitf720a27a1f41c9fe8f079df5252f5535ad6338f4 (patch)
treeaec6ed7ef83289516201e4f56cb01d55fc9c3c7a
parent06ae2b2c9879cfdc10d38cc4fbd83e32f1c79986 (diff)
downloadofono-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.c25
-rw-r--r--gatchat/ppp.c23
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)