ssize_t udp_recvfrom( void *prot_data, void *buf, ssize_t len, i4sockaddr *saddr, int flags, bigtime_t timeout) { udp_endpoint *e = prot_data; udp_queue_elem *qe; int err; ssize_t ret; retry: //#warning timeout ignored #if 1 if(flags & SOCK_FLAG_TIMEOUT) err = hal_sem_acquire_etc( &e->blocking_sem, 1, SEM_FLAG_TIMEOUT, timeout ); else #endif err = sem_acquire(e->blocking_sem); //if(err < 0) if(err) return -err; // pop an item off the list, if there are any mutex_lock(&e->lock); qe = udp_queue_pop(&e->q); mutex_unlock(&e->lock); if(!qe) { #if 1||NET_CHATTY printf("UDP read retry"); #endif goto retry; } // we have the data, copy it out //err = cbuf_user_memcpy_from_chain(buf, qe->buf, 0, min(qe->len, len)); err = cbuf_memcpy_from_chain(buf, qe->buf, 0, min(qe->len, len)); if(err < 0) { ret = err; goto out; } ret = qe->len; // copy the address out if(saddr) { saddr->addr.len = 4; saddr->addr.type = ADDR_TYPE_IP; NETADDR_TO_IPV4(saddr->addr) = qe->src_address; saddr->port = qe->src_port; } out: // free this queue entry cbuf_free_chain(qe->buf); kfree(qe); return ret; }
static void sem_etc(void *a) { (void) a; rc = hal_sem_acquire_etc( &test_sem_0, 1, SEM_FLAG_TIMEOUT, 1000L*200L ); sem_released = 1; }