From 0ab372585f57c80202a432bd757d52088de80850 Mon Sep 17 00:00:00 2001
From: Paul Sokolovsky <pfalcon@users.sourceforge.net>
Date: Fri, 20 May 2016 22:20:37 +0300
Subject: [PATCH] extmod/moduos_dupterm: Dumpterm subsystem is responsible for
 closing stream.

Make dupterm subsystem close a term stream object when EOF or error occurs.
There's no other party than dupterm itself in a better position to do this,
and this is required to properly reclaim stream resources, especially if
multiple dupterm sessions may be established (e.g. as networking
connections).
---
 esp8266/esp_mphal.c     |  7 ++-----
 extmod/misc.h           |  1 +
 extmod/moduos_dupterm.c | 15 ++++++++++++---
 3 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/esp8266/esp_mphal.c b/esp8266/esp_mphal.c
index 25f1a9322..ec5da7d3d 100644
--- a/esp8266/esp_mphal.c
+++ b/esp8266/esp_mphal.c
@@ -171,16 +171,13 @@ static int call_dupterm_read(void) {
         mp_buffer_info_t bufinfo;
         mp_get_buffer_raise(res, &bufinfo, MP_BUFFER_READ);
         if (bufinfo.len == 0) {
-            MP_STATE_PORT(term_obj) = NULL;
-            mp_printf(&mp_plat_print, "dupterm: EOF received, deactivating\n");
+            mp_uos_deactivate("dupterm: EOF received, deactivating\n", MP_OBJ_NULL);
             return -1;
         }
         nlr_pop();
         return *(byte*)bufinfo.buf;
     } else {
-        MP_STATE_PORT(term_obj) = NULL;
-        mp_printf(&mp_plat_print, "dupterm: Exception in read() method, deactivating: ");
-        mp_obj_print_exception(&mp_plat_print, nlr.ret_val);
+        mp_uos_deactivate("dupterm: Exception in read() method, deactivating: ", nlr.ret_val);
     }
 
     return -1;
diff --git a/extmod/misc.h b/extmod/misc.h
index 39bfd5ecb..634ea924d 100644
--- a/extmod/misc.h
+++ b/extmod/misc.h
@@ -34,6 +34,7 @@ MP_DECLARE_CONST_FUN_OBJ(mp_uos_dupterm_obj);
 
 #if MICROPY_PY_OS_DUPTERM
 void mp_uos_dupterm_tx_strn(const char *str, size_t len);
+void mp_uos_deactivate(const char *msg, mp_obj_t exc);
 #else
 #define mp_uos_dupterm_tx_strn(s, l)
 #endif
diff --git a/extmod/moduos_dupterm.c b/extmod/moduos_dupterm.c
index 41b8b3c81..4c9f9e494 100644
--- a/extmod/moduos_dupterm.c
+++ b/extmod/moduos_dupterm.c
@@ -31,9 +31,20 @@
 #include "py/nlr.h"
 #include "py/runtime.h"
 #include "py/objtuple.h"
+#include "py/stream.h"
 
 #if MICROPY_PY_OS_DUPTERM
 
+void mp_uos_deactivate(const char *msg, mp_obj_t exc) {
+    mp_obj_t term = MP_STATE_PORT(term_obj);
+    MP_STATE_PORT(term_obj) = NULL;
+    mp_printf(&mp_plat_print, msg);
+    if (exc != MP_OBJ_NULL) {
+        mp_obj_print_exception(&mp_plat_print, exc);
+    }
+    mp_stream_close(term);
+}
+
 void mp_uos_dupterm_tx_strn(const char *str, size_t len) {
     if (MP_STATE_PORT(term_obj) != MP_OBJ_NULL) {
         nlr_buf_t nlr;
@@ -44,9 +55,7 @@ void mp_uos_dupterm_tx_strn(const char *str, size_t len) {
             mp_call_method_n_kw(1, 0, write_m);
             nlr_pop();
         } else {
-            MP_STATE_PORT(term_obj) = NULL;
-            mp_printf(&mp_plat_print, "dupterm: Exception in write() method, deactivating: ");
-            mp_obj_print_exception(&mp_plat_print, nlr.ret_val);
+            mp_uos_deactivate("dupterm: Exception in write() method, deactivating: ", nlr.ret_val);
         }
     }
 }
-- 
GitLab