Index: lwip/include/lwip/sys.h
===================================================================
--- lwip/include/lwip/sys.h	(revision 37191)
+++ lwip/include/lwip/sys.h	(revision 37192)
@@ -138,6 +138,7 @@
 
 /* Thread functions. */
 sys_thread_t sys_thread_new(char *name, void (* thread)(void *arg), void *arg, int stacksize, int prio);
+u32_t sys_thread_join(sys_thread_t id, u32_t timeout);
 
 /* The following functions are used only in Unix code, and
    can be omitted when porting the stack. */
Index: lwip/include/lwip/tcpip.h
===================================================================
--- lwip/include/lwip/tcpip.h	(revision 37191)
+++ lwip/include/lwip/tcpip.h	(revision 37192)
@@ -65,6 +65,7 @@
 #endif /* LWIP_TCPIP_CORE_LOCKING */
 
 void tcpip_init(void (* tcpip_init_done)(void *), void *arg);
+void tcpip_shutdown(void);
 
 #if LWIP_NETCONN
 err_t tcpip_apimsg(struct api_msg *apimsg);
Index: lwip/include/lwip/tcp.h
===================================================================
--- lwip/include/lwip/tcp.h	(revision 37191)
+++ lwip/include/lwip/tcp.h	(revision 37192)
@@ -539,6 +539,8 @@
 u16_t tcp_eff_send_mss(u16_t sendmss, struct ip_addr *addr);
 #endif /* TCP_CALCULATE_EFF_SEND_MSS */
 
+void tcp_kill_all_connections(void);
+
 extern struct tcp_pcb *tcp_input_pcb;
 extern u32_t tcp_ticks;
 
Index: lwip/core/tcp.c
===================================================================
--- lwip/core/tcp.c	(revision 37191)
+++ lwip/core/tcp.c	(revision 37192)
@@ -1249,6 +1249,25 @@
 }
 #endif /* TCP_CALCULATE_EFF_SEND_MSS */
 
+/**
+ * Kills all of the tcp connections known to the system.
+ * 
+ *
+ * Used when shutting down lwip.
+ */
+void
+tcp_kill_all_connections(void)
+{
+  struct tcp_pcb *pcb;
+
+  for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
+	  tcp_abort(pcb);
+  }
+  for(pcb = tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) {
+	  tcp_abort(pcb);
+  }
+}
+
 #if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG
 /**
  * Print a tcp header for debugging purposes.
Index: lwip/api/tcpip.c
===================================================================
--- lwip/api/tcpip.c	(revision 37191)
+++ lwip/api/tcpip.c	(revision 37192)
@@ -58,6 +58,7 @@
 static void (* tcpip_init_done)(void *arg);
 static void *tcpip_init_done_arg;
 static sys_mbox_t mbox = SYS_MBOX_NULL;
+static sys_thread_t tcpip_thread_id;
 
 #if LWIP_TCPIP_CORE_LOCKING
 /** The global semaphore to lock the stack. */
@@ -233,6 +234,7 @@
 tcpip_thread(void *arg)
 {
   struct tcpip_msg *msg;
+  sys_mbox_t local_mbox;
   LWIP_UNUSED_ARG(arg);
 
 #if IP_REASSEMBLY
@@ -260,8 +262,16 @@
   }
 
   LOCK_TCPIP_CORE();
+  SYS_ARCH_GET(mbox,local_mbox);
   while (1) {                          /* MAIN Loop */
-    sys_mbox_fetch(mbox, (void *)&msg);
+	if (mbox == NULL){
+		if(sys_mbox_tryfetch(local_mbox, (void *)&msg) == SYS_ARCH_TIMEOUT) {
+			// No more messages to handle. Terminate the thread.
+			break;
+		}
+	} else {
+		sys_mbox_fetch(local_mbox, (void *)&msg);
+	}
     switch (msg->type) {
 #if LWIP_NETCONN
     case TCPIP_MSG_API:
@@ -322,8 +332,11 @@
 tcpip_input(struct pbuf *p, struct netif *inp)
 {
   struct tcpip_msg *msg;
+  
 
-  if (mbox != SYS_MBOX_NULL) {
+  sys_mbox_t local_mbox;
+  SYS_ARCH_GET(mbox,local_mbox);
+  if (local_mbox != SYS_MBOX_NULL) {
     msg = memp_malloc(MEMP_TCPIP_MSG_INPKT);
     if (msg == NULL) {
       return ERR_MEM;
@@ -332,7 +345,7 @@
     msg->type = TCPIP_MSG_INPKT;
     msg->msg.inp.p = p;
     msg->msg.inp.netif = inp;
-    if (sys_mbox_trypost(mbox, msg) != ERR_OK) {
+    if (sys_mbox_trypost(local_mbox, msg) != ERR_OK) {
       memp_free(MEMP_TCPIP_MSG_INPKT, msg);
       return ERR_MEM;
     }
@@ -356,8 +369,9 @@
 tcpip_callback_with_block(void (*f)(void *ctx), void *ctx, u8_t block)
 {
   struct tcpip_msg *msg;
-
-  if (mbox != SYS_MBOX_NULL) {
+  sys_mbox_t local_mbox;
+  SYS_ARCH_GET(mbox,local_mbox);
+  if (local_mbox != SYS_MBOX_NULL) {
     msg = memp_malloc(MEMP_TCPIP_MSG_API);
     if (msg == NULL) {
       return ERR_MEM;
@@ -367,9 +381,9 @@
     msg->msg.cb.f = f;
     msg->msg.cb.ctx = ctx;
     if (block) {
-      sys_mbox_post(mbox, msg);
+      sys_mbox_post(local_mbox, msg);
     } else {
-      if (sys_mbox_trypost(mbox, msg) != ERR_OK) {
+      if (sys_mbox_trypost(local_mbox, msg) != ERR_OK) {
         memp_free(MEMP_TCPIP_MSG_API, msg);
         return ERR_MEM;
       }
@@ -384,7 +398,9 @@
 {
   struct tcpip_msg *msg;
 
-  if (mbox != SYS_MBOX_NULL) {
+  sys_mbox_t local_mbox;
+  SYS_ARCH_GET(mbox,local_mbox);
+  if (local_mbox != SYS_MBOX_NULL) {
     msg = memp_malloc(MEMP_TCPIP_MSG_API);
     if (msg == NULL) {
       return ERR_MEM;
@@ -394,12 +410,23 @@
     msg->msg.tmo.msecs = msecs;
     msg->msg.tmo.h = h;
     msg->msg.tmo.arg = arg;
-    sys_mbox_post(mbox, msg);
+    sys_mbox_post(local_mbox, msg);
     return ERR_OK;
   }
   return ERR_VAL;
 }
 
+static void tcpip_shutdown_internal(void* ctx) {
+	LWIP_UNUSED_ARG(ctx);
+	tcp_kill_all_connections();
+	SYS_ARCH_SET(mbox,NULL);
+}
+
+void tcpip_shutdown(void) {
+	tcpip_callback_with_block(tcpip_shutdown_internal,NULL,1);
+	sys_thread_join(tcpip_thread_id, 0);
+}
+
 #if LWIP_NETCONN
 /**
  * Call the lower part of a netconn_* function
@@ -414,10 +441,12 @@
 {
   struct tcpip_msg msg;
   
-  if (mbox != SYS_MBOX_NULL) {
+  sys_mbox_t local_mbox;
+  SYS_ARCH_GET(mbox,local_mbox);
+  if (local_mbox != SYS_MBOX_NULL) {
     msg.type = TCPIP_MSG_API;
     msg.msg.apimsg = apimsg;
-    sys_mbox_post(mbox, &msg);
+    sys_mbox_post(local_mbox, &msg);
     sys_arch_sem_wait(apimsg->msg.conn->op_completed, 0);
     return ERR_OK;
   }
@@ -459,7 +488,9 @@
 {
   struct tcpip_msg msg;
   
-  if (mbox != SYS_MBOX_NULL) {
+  sys_mbox_t local_mbox;
+  SYS_ARCH_GET(mbox,local_mbox);
+  if (local_mbox != SYS_MBOX_NULL) {
     netifapimsg->msg.sem = sys_sem_new(0);
     if (netifapimsg->msg.sem == SYS_SEM_NULL) {
       netifapimsg->msg.err = ERR_MEM;
@@ -468,7 +499,7 @@
     
     msg.type = TCPIP_MSG_NETIFAPI;
     msg.msg.netifapimsg = netifapimsg;
-    sys_mbox_post(mbox, &msg);
+    sys_mbox_post(local_mbox, &msg);
     sys_sem_wait(netifapimsg->msg.sem);
     sys_sem_free(netifapimsg->msg.sem);
     return netifapimsg->msg.err;
@@ -510,12 +541,14 @@
 
   tcpip_init_done = initfunc;
   tcpip_init_done_arg = arg;
+  // We can do this here without "SYS_ARCH_PROTECT" since the thread is not alive yet.
   mbox = sys_mbox_new(TCPIP_MBOX_SIZE);
 #if LWIP_TCPIP_CORE_LOCKING
   lock_tcpip_core = sys_sem_new(1);
 #endif /* LWIP_TCPIP_CORE_LOCKING */
 
-  sys_thread_new(TCPIP_THREAD_NAME, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO);
+  tcpip_thread_id = sys_thread_new(TCPIP_THREAD_NAME, tcpip_thread, NULL, 
+	                               TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO);
 }
 
 #endif /* !NO_SYS */
Index: lwip/arch/sys_arch.c
===================================================================
--- lwip/arch/sys_arch.c	(revision 37191)
+++ lwip/arch/sys_arch.c	(revision 37192)
@@ -248,6 +248,7 @@
     h = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)function, arg, 0, &(new_thread->id));
     LWIP_ASSERT("h != 0", h != 0);
     LWIP_ASSERT("h != -1", h != INVALID_HANDLE_VALUE);
+	CloseHandle(h);
 
     SYS_ARCH_UNPROTECT(lev);
     return new_thread->id;
@@ -255,6 +256,21 @@
   return 0;
 }
 
+u32_t sys_thread_join(sys_thread_t id, u32_t timeout) {
+	HANDLE h;
+	u32_t retVal = 0;
+	h = OpenThread(SYNCHRONIZE,FALSE,id);
+	if (h == NULL) {
+		// Thread doesn't exist or can't open thread, we waited "zero" time.
+		return 0;
+	}
+	// Since we have a handle, we can wait on it the same way we wait on 
+	// semaphores.
+	retVal = sys_arch_sem_wait(h,timeout);
+	CloseHandle(h);
+	return retVal;
+}
+
 sys_mbox_t sys_mbox_new(int size)
 {
   struct lwip_mbox *new_mbox;
