sockets - sendto() dgrams do not block for ENOBUFS on OSX -


this more of observation , suggestion whats best way handle scenario.

i have 2 threads 1 pumps in data , receives data , lot of work before sending socket. both threads connected via domain socket. protocol used here udp. did not want use tcp stream based, means if there little space in queue data split , sent. bad iam sending data should not split. hence used dgram. interestingly when send thread overwhelms recv thread pumping data, @ point domain socket buffer gets filled , sendto() returns enobufs. of opinion should happen, sendto() block until buffer available. desired behaviour. not seem case. solve problem in rather weird way.

  • cpu yield method if enobufs, sched_yield(); there no pthread_yield() in osx. after try resend again. if fails keep doing same until taken. bad iam wasting cpu cycles doing useless. love if sendto() blocked.

  • sleep method tried solve same issue using sleep(1) instead of sched_yield() of no use sleep() put process sleep instead of send thread.

both of them not seem work me , iam running out of options. can suggest best way handle issue? there clever tricks iam not aware of can reduce unnecessary cpu cycles? btw, man page says sentto() wrong, based on discussion http://lists.freebsd.org/pipermail/freebsd-hackers/2004-january/005385.html

the upd code in kernel:

the udp_output function in /sys/netinet/udp_usrreq.c, seems clear:           /*           * calculate data length , mbuf           * udp , ip headers.           */          m_prepend(m, sizeof(struct udpiphdr), m_dontwait);          if (m == 0) {                  error = enobufs;                  if (addr)                          splx(s);                  goto release;          } 

i'm not sure why sendto() isn't blocking you... might try calling function before each call sendto():

#include <stdio.h> #include <sys/select.h>  // won't return until there space available on socket writing void waituntilsocketisreadyforwrite(int socketfd) {    fd_set writeset;    fd_zero(&writeset);    fd_set(socketfd, &writeset);    if (select(socketfd+1, null, &writeset, null, null) < 0) perror("select"); } 

btw how big packets trying send?


Comments

Popular posts from this blog

jquery - How can I dynamically add a browser tab? -

node.js - Getting the socket id,user id pair of a logged in user(s) -

keyboard - C++ GetAsyncKeyState alternative -