/** * Go through timeout list (for this task only) and remove the first matching * entry, even though the timeout has not triggered yet. * * @note This function only works as expected if there is only one timeout * calling 'handler' in the list of timeouts. * * @param handler callback function that would be called by the timeout * @param arg callback argument that would be passed to handler */ public void sys_untimeout(sys_timeout_handler handler, object arg) { sys_timeo prev_t, t; if (next_timeout == null) { return; } for (t = next_timeout, prev_t = null; t != null; prev_t = t, t = t.next) { if ((t.h == handler) && (t.arg == arg)) { /* We have a match */ /* Unlink from previous in list */ if (prev_t == null) { next_timeout = t.next; } else { prev_t.next = t.next; } /* If not the last one, add time of this one back to next */ if (t.next != null) { t.next.time += t.time; } lwip.memp_free(memp_t.MEMP_SYS_TIMEOUT, t); return; } } return; }
public void sys_timeout(int msecs, sys_timeout_handler handler, object arg) #endif // LWIP_DEBUG_TIMERNAMES { sys_timeo timeout, t; timeout = (sys_timeo)lwip.memp_malloc(memp_t.MEMP_SYS_TIMEOUT); if (timeout == null) { lwip.LWIP_ASSERT("sys_timeout: timeout != null, pool MEMP_SYS_TIMEOUT is empty", timeout != null); return; } timeout.next = null; timeout.h = handler; timeout.arg = arg; timeout.time = msecs; #if LWIP_DEBUG_TIMERNAMES timeout.handler_name = handler_name; lwip.LWIP_DEBUGF(opt.TIMERS_DEBUG, "sys_timeout: {0} msecs={1} handler={2} arg={3}\n", timeout, msecs, handler_name, arg)); #endif // LWIP_DEBUG_TIMERNAMES if (next_timeout == null) { next_timeout = timeout; return; } if (next_timeout.time > msecs) { next_timeout.time -= msecs; timeout.next = next_timeout; next_timeout = timeout; } else { for (t = next_timeout; t != null; t = t.next) { timeout.time -= t.time; if (t.next == null || t.next.time > timeout.time) { if (t.next != null) { t.next.time -= timeout.time; } timeout.next = t.next; t.next = timeout; break; } } } }
/** Handle timeouts for NO_SYS==1 (i.e. without using * tcpip_thread/sys_timeouts_mbox_fetch(). Uses sys_now() to call timeout * handler functions when timeouts expire. * * Must be called periodically from your main loop. */ public void sys_check_timeouts() { if (next_timeout != null) { sys_timeo tmptimeout; uint diff; sys_timeout_handler handler; object arg; byte had_one; uint now; now = sys_now(); /* this cares for wraparounds */ diff = now - timeouts_last_time; do { #if PBUF_POOL_FREE_OOSEQ lwip.PBUF_CHECK_FREE_OOSEQ(); #endif // PBUF_POOL_FREE_OOSEQ had_one = 0; tmptimeout = next_timeout; if ((tmptimeout != null) && (tmptimeout.time <= diff)) { /* timeout has expired */ had_one = 1; timeouts_last_time = now; diff = (uint)(diff - tmptimeout.time); next_timeout = tmptimeout.next; handler = tmptimeout.h; arg = tmptimeout.arg; #if LWIP_DEBUG_TIMERNAMES if (handler != null) { lwip.LWIP_DEBUGF(opt.TIMERS_DEBUG, "sct calling h={0} arg={1}\n", tmptimeout.handler_name, arg); } #endif // LWIP_DEBUG_TIMERNAMES lwip.memp_free(memp_t.MEMP_SYS_TIMEOUT, tmptimeout); if (handler != null) { handler(arg); } } /* repeat until all expired timers have been called */ } while (had_one != 0); } }
/** * Wait (forever) for a message to arrive in an mbox. * While waiting, timeouts are processed. * * @param mbox the mbox to fetch the message from * @param msg the place to store the message */ public void sys_timeouts_mbox_fetch<P>(sys_mbox_t mbox, out P msg) where P : class { int time_needed; sys_timeo tmptimeout; sys_timeout_handler handler; object arg; msg = null; again: if (next_timeout == null) { time_needed = sys_arch_mbox_fetch(mbox, out msg, 0); } else { if (next_timeout.time > 0) { time_needed = sys_arch_mbox_fetch(mbox, out msg, next_timeout.time); } else { time_needed = sys.SYS_ARCH_TIMEOUT; } if (time_needed == sys.SYS_ARCH_TIMEOUT) { /* If time == sys.SYS_ARCH_TIMEOUT, a timeout occured before a message could be fetched. We should now call the timeout handler and deallocate the memory allocated for the timeout. */ tmptimeout = next_timeout; next_timeout = tmptimeout.next; handler = tmptimeout.h; arg = tmptimeout.arg; #if LWIP_DEBUG_TIMERNAMES if (handler != null) { lwip.LWIP_DEBUGF(opt.TIMERS_DEBUG, "stmf calling h={0} arg={1}\n", tmptimeout.handler_name, arg); } #endif // LWIP_DEBUG_TIMERNAMES lwip.memp_free(memp_t.MEMP_SYS_TIMEOUT, tmptimeout); if (handler != null) { /* For LWIP_TCPIP_CORE_LOCKING, lock the core before calling the timeout handler function. */ lwip.tcpip.LOCK_TCPIP_CORE(); handler(arg); lwip.tcpip.UNLOCK_TCPIP_CORE(); } tcpip.LWIP_TCPIP_THREAD_ALIVE(); /* We try again to fetch a message from the mbox. */ goto again; } else { /* If time != sys.SYS_ARCH_TIMEOUT, a message was received before the timeout occured. The time variable is set to the number of milliseconds we waited for the message. */ if (time_needed < next_timeout.time) { next_timeout.time -= time_needed; } else { next_timeout.time = 0; } } } }
internal memp memp_malloc(memp_t type) { memp memp; switch (type) { #if LWIP_RAW case memp_t.MEMP_RAW_PCB: memp = new raw_pcb(this); break; #endif #if LWIP_UDP case memp_t.MEMP_UDP_PCB: memp = new udp_pcb(this); break; #endif #if LWIP_TCP case memp_t.MEMP_TCP_PCB: memp = new tcp_pcb(this); break; case memp_t.MEMP_TCP_PCB_LISTEN: memp = new tcp_pcb_listen(this); break; case memp_t.MEMP_TCP_SEG: memp = new tcp_seg(this); break; #endif #if IP_REASSEMBLY case memp_t.MEMP_REASSDATA: memp = new ip_reassdata(this); break; case memp_t.MEMP_FRAG_PBUF: memp = new frag_pbuf(this); break; #endif #if LWIP_NETCONN case memp_t.MEMP_NETBUF: memp = new netbuf(this); break; case memp_t.MEMP_NETCONN: memp = new netconn(this); break; #endif #if false //!NO_SYS case memp_t.MEMP_TCPIP_MSG_API: memp = new tcpip_msg(this); break; case memp_t.MEMP_TCPIP_MSG_INPKT: memp = new tcpip_msg(this); break; #endif #if LWIP_ARP && ARP_QUEUEING case memp_t.MEMP_ARP_QUEUE: memp = new etharp_q_entry(this); break; #endif #if LWIP_IGMP case memp_t.MEMP_IGMP_GROUP: memp = new igmp_group(this); break; #endif #if false //(!NO_SYS || (NO_SYS && !NO_SYS_NO_TIMERS)) case memp_t.MEMP_SYS_TIMEOUT: memp = new sys_timeo(this); break; #endif #if LWIP_SNMP case memp_t.MEMP_SNMP_ROOTNODE: memp = new mib_list_rootnode(this); break; case memp_t.MEMP_SNMP_NODE: memp = new mib_list_node(this); break; case memp_t.MEMP_SNMP_VARBIND: memp = new snmp_varbind(this); break; case memp_t.MEMP_SNMP_VALUE: memp = new snmp_value(this); break; #endif #if LWIP_DNS && LWIP_SOCKET case memp_t.MEMP_NETDB: memp = new netdb(this); break; #endif #if LWIP_DNS && DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC case memp_t.MEMP_LOCALHOSTLIST: memp = new local_hostlist_entry(this); break; #endif #if PPP_SUPPORT && PPPOE_SUPPORT case memp_t.MEMP_PPPOE_IF: memp = new pppoe_softc(this); break; #endif default: throw new InvalidOperationException(); } memp._type = type; memp_heap.AddLast(memp); return(memp); }