n4 ring_init(vpp ring_pptr, u4 unit_num, u4 unit_size) { u8 size; ring_p ring; /* size must be a power of 2 */ if (IS_NL(ring_pptr) || IS_ZR(unit_num) || IS_ZR(unit_size) || IS_NZR(unit_num & (unit_num - 1))) { RET_INT(-1, "@ring = %p, @unit_num = %u, @unit_size = %u", ring_pptr, unit_num, unit_size); } size = sizeof(ring_t) + (u8)(unit_size) * (u8)(unit_num); if (IS_NL(ALLOC(ring, size))) { RET_INT(-2, "ALLOC(size = %llu) = %p", size, ring); } SET_ZERO(ring, sizeof(ring_t)); ring->type = RING_MP_MC; ring->unit_num = unit_num; ring->unit_size = unit_size; *ring_pptr = ring; RET_INT(0, nil_str); }
/** * Accept a new connection from peer. * @param msgPtr base object reference. * @param newPtr new object for the accepted connection. * @note addr and newPtr only applicable for sockets. * @param addr reference for storing address of the remote node. * @return The \c error-code else success is returned. */ inline genErr_t msg_accept (msg_base msgPtr, msg_base *newPtr, msg_addr addr) { validateObj (msgPtr); if(msgPtr->_connType != MSG_PMSGQ) { int rc; genErr_t retVal; struct sockaddr peerAddr; socklen_t sockLen = 0; SET_ZERO(peerAddr); retVal = msg_baseInit (newPtr, msgPtr->_mObj); if(retVal != SUCCESS) return retVal; rc = accept (msgPtr->_connData._sock._sockFD, &peerAddr, &sockLen); if (rc == -1) return errno2EC (errno); if(addr != NULL) { inet_ntop(msgPtr->_connData._sock._self->ai_family, &peerAddr, addr->nodeID, sockLen); snprintf(addr->appID, APP_ID_SIZE, "%d", (peerAddr.sa_family == AF_INET)? ((struct sockaddr_in*)&peerAddr)->sin_port: ((struct sockaddr_in6*)&peerAddr)->sin6_port); } if(*newPtr != NULL) { //Store the new socket fd. (*newPtr)->_connData._sock._sockFD = rc; (*newPtr)->_connType = msgPtr->_connType; } } return SUCCESS; }
/** * Send message to peer. * @note Send irrespective of protocols. * @param msgPtr base object reference. * @param retCount the number of bytes sent. * @param msgVec the vector base of buffers. * @return The \c error-code else success is returned. */ inline genErr_t msg_sendVec (msg_base msgPtr, int *retCount, vec_io vec) { int rc = -1; validateObj (msgPtr); *retCount = -1; if(msgPtr->_connType != MSG_PMSGQ) { int flags = 0; struct msghdr msg; SET_ZERO(msg); msg.msg_iov = vec->ioVecPtr; msg.msg_iovlen = vec->vecCount; rc = sendmsg(msgPtr->_connData._sock._sockFD, &msg, flags); if (rc == -1) return errno2EC (errno); } else { rc = mq_send(msgPtr->_connData._mq._mqFD, (char *)vec->ioVecPtr->iov_base, vec->ioVecPtr->iov_len, vec->priority); if (rc == -1) return errno2EC (errno); /*Add the request length as the sent lenght in case of MQ*/ rc = vec->ioVecPtr->iov_len; } *retCount = rc; return SUCCESS; }
/** * Receive message from peer. * @note Receive irrespective of protocols. * @param msgPtr base object reference. * @param retCount the number of bytes recevied. * @param msgVec the vector base of buffers. * @return The \c error-code else success is returned. */ inline genErr_t msg_recvVec (msg_base msgPtr, int *retCount, vec_io vec) { int rc = -1; validateObj (msgPtr); *retCount = -1; if(msgPtr->_connType != MSG_PMSGQ) { int flags = 0; struct msghdr msg; SET_ZERO(msg); msg.msg_iov = vec->ioVecPtr; msg.msg_iovlen = vec->vecCount; rc = recvmsg(msgPtr->_connData._sock._sockFD, &msg, flags); if (rc == -1) return errno2EC (errno); } else { rc = mq_receive(msgPtr->_connData._mq._mqFD, (char *)vec->ioVecPtr->iov_base, vec->ioVecPtr->iov_len, &vec->priority); if (rc == -1) return errno2EC (errno); } *retCount = rc; return SUCCESS; }
void W_CheckTimerHandlers(void) { TimerHandler *handler; struct timeval now; if (!timerHandler) { W_FlushASAPNotificationQueue(); return; } rightNow(&now); handler = timerHandler; while (handler && IS_AFTER(now, handler->when)) { if (!IS_ZERO(handler->when)) { SET_ZERO(handler->when); (*handler->callback)(handler->clientData); } handler = handler->next; } while (timerHandler && IS_ZERO(timerHandler->when)) { handler = timerHandler; timerHandler = timerHandler->next; if (handler->nextDelay > 0) { handler->when = now; addmillisecs(&handler->when, handler->nextDelay); enqueueTimerHandler(handler); } else { wfree(handler); } } W_FlushASAPNotificationQueue(); }
/* * This functions will handle input events on all registered file descriptors. * Input: * - waitForInput - True if we want the function to wait until an event * appears on a file descriptor we watch, False if we * want the function to immediately return if there is * no data available on the file descriptors we watch. * - inputfd - Extra input file descriptor to watch for input. * This is only used when called from wevent.c to watch * on ConnectionNumber(dpy) to avoid blocking of X events * if we wait for input from other file handlers. * Output: * if waitForInput is False, the function will return False if there are no * input handlers registered, or if there is no data * available on the registered ones, and will return True * if there is at least one input handler that has data * available. * if waitForInput is True, the function will return False if there are no * input handlers registered, else it will block until an * event appears on one of the file descriptors it watches * and then it will return True. * * If the retured value is True, the input handlers for the corresponding file * descriptors are also called. * * Parametersshould be passed like this: * - from wevent.c: * waitForInput - apropriate value passed by the function who called us * inputfd = ConnectionNumber(dpy) * - from wutil.c: * waitForInput - apropriate value passed by the function who called us * inputfd = -1 * */ Bool W_HandleInputEvents(Bool waitForInput, int inputfd) { #if defined(HAVE_POLL) && defined(HAVE_POLL_H) && !defined(HAVE_SELECT) struct poll fd *fds; InputHandler *handler; int count, timeout, nfds, i, extrafd; extrafd = (inputfd < 0) ? 0 : 1; if (inputHandler) nfds = WMGetArrayItemCount(inputHandler); else nfds = 0; if (!extrafd && nfds==0) { W_FlushASAPNotificationQueue(); return False; } fds = wmalloc((nfds+extrafd) * sizeof(struct pollfd)); if (extrafd) { /* put this to the end of array to avoid using ranges from 1 to nfds+1 */ fds[nfds].fd = inputfd; fds[nfds].events = POLLIN; } /* use WM_ITERATE_ARRAY() here */ for (i = 0; i<nfds; i++) { handler = WMGetFromArray(inputHandler, i); fds[i].fd = handler->fd; fds[i].events = 0; if (handler->mask & WIReadMask) fds[i].events |= POLLIN; if (handler->mask & WIWriteMask) fds[i].events |= POLLOUT; #if 0 /* FIXME */ if (handler->mask & WIExceptMask) FD_SET(handler->fd, &eset); #endif } /* * Setup the timeout to the estimated time until the * next timer expires. */ if (!waitForInput) { timeout = 0; } else if (timerPending()) { struct timeval tv; delayUntilNextTimerEvent(&tv); timeout = tv.tv_sec * 1000 + tv.tv_usec / 1000; } else { timeout = -1; } count = poll(fds, nfds+extrafd, timeout); if (count>0 && nfds>0) { WMArray *handlerCopy = WMDuplicateArray(inputHandler); int mask; /* use WM_ITERATE_ARRAY() here */ for (i=0; i<nfds; i++) { handler = WMGetFromArray(handlerCopy, i); /* check if the handler still exist or was removed by a callback */ if (WMGetFirstInArray(inputHandler, handler) == WANotFound) continue; mask = 0; if ((handler->mask & WIReadMask) && (fds[i].revents & (POLLIN|POLLRDNORM|POLLRDBAND|POLLPRI))) mask |= WIReadMask; if ((handler->mask & WIWriteMask) && (fds[i].revents & (POLLOUT | POLLWRBAND))) mask |= WIWriteMask; if ((handler->mask & WIExceptMask) && (fds[i].revents & (POLLHUP | POLLNVAL | POLLERR))) mask |= WIExceptMask; if (mask!=0 && handler->callback) { (*handler->callback)(handler->fd, mask, handler->clientData); } } WMFreeArray(handlerCopy); } wfree(fds); W_FlushASAPNotificationQueue(); return (count > 0); #else #ifdef HAVE_SELECT struct timeval timeout; struct timeval *timeoutPtr; fd_set rset, wset, eset; int maxfd, nfds, i; int count; InputHandler *handler; if (inputHandler) nfds = WMGetArrayItemCount(inputHandler); else nfds = 0; if (inputfd<0 && nfds==0) { W_FlushASAPNotificationQueue(); return False; } FD_ZERO(&rset); FD_ZERO(&wset); FD_ZERO(&eset); if (inputfd < 0) { maxfd = 0; } else { FD_SET(inputfd, &rset); maxfd = inputfd; } /* use WM_ITERATE_ARRAY() here */ for (i=0; i<nfds; i++) { handler = WMGetFromArray(inputHandler, i); if (handler->mask & WIReadMask) FD_SET(handler->fd, &rset); if (handler->mask & WIWriteMask) FD_SET(handler->fd, &wset); if (handler->mask & WIExceptMask) FD_SET(handler->fd, &eset); if (maxfd < handler->fd) maxfd = handler->fd; } /* * Setup the timeout to the estimated time until the * next timer expires. */ if (!waitForInput) { SET_ZERO(timeout); timeoutPtr = &timeout; } else if (timerPending()) { delayUntilNextTimerEvent(&timeout); timeoutPtr = &timeout; } else { timeoutPtr = (struct timeval*)0; } count = select(1 + maxfd, &rset, &wset, &eset, timeoutPtr); if (count>0 && nfds>0) { WMArray *handlerCopy = WMDuplicateArray(inputHandler); int mask; /* use WM_ITERATE_ARRAY() here */ for (i=0; i<nfds; i++) { handler = WMGetFromArray(handlerCopy, i); /* check if the handler still exist or was removed by a callback */ if (WMGetFirstInArray(inputHandler, handler) == WANotFound) continue; mask = 0; if ((handler->mask & WIReadMask) && FD_ISSET(handler->fd, &rset)) mask |= WIReadMask; if ((handler->mask & WIWriteMask) && FD_ISSET(handler->fd, &wset)) mask |= WIWriteMask; if ((handler->mask & WIExceptMask) && FD_ISSET(handler->fd, &eset)) mask |= WIExceptMask; if (mask!=0 && handler->callback) { (*handler->callback)(handler->fd, mask, handler->clientData); } } WMFreeArray(handlerCopy); } W_FlushASAPNotificationQueue(); return (count > 0); #else /* not HAVE_SELECT, not HAVE_POLL */ # error Neither select nor poll. You lose. #endif /* HAVE_SELECT */ #endif /* HAVE_POLL */ }
/** * Sets the self address (for bind) and the remote address. The * function also creates the sockets (depending upon the address). * @note Use blank addr for any addr in case of bind * @param msgPtr message base object reference. * @param type connection type. * @param selfAddr The self addr. Mostly applicable for servers. Can be NULL. * @param remoteAddr The peer address. Can be NULL in cases of servers. * @return The \c error-code else success is returned. */ inline genErr_t msg_setAddr (msg_base msgPtr, msg_e_connType type, msg_addr selfAddr, msg_addr remoteAddr) { genErr_t retVal = SUCCESS; validateObj (msgPtr); msgPtr->_connType = type; if (type != MSG_PMSGQ) { int rc=0; int sockType = (type == MSG_STREAM)?SOCK_STREAM:SOCK_DGRAM; int family = AF_UNSPEC; int protocol = 0; struct addrinfo hints; SET_ZERO(hints); if(selfAddr) { int nodeIDLen = strlen(selfAddr->nodeID); hints.ai_family = AF_UNSPEC; hints.ai_socktype = sockType; hints.ai_flags = (nodeIDLen==0)?AI_PASSIVE:0; hints.ai_flags |= AI_NUMERICSERV; rc = getaddrinfo((nodeIDLen!=0)?selfAddr->nodeID:NULL, (strlen(selfAddr->appID)!=0)?selfAddr->appID:NULL, &hints, &msgPtr->_connData._sock._self); if (rc != 0) { // printf("%s", gai_strerror(rc)); return ADDRINFO_FAIL; } sockType = msgPtr->_connData._sock._self->ai_socktype; family = msgPtr->_connData._sock._self->ai_family; protocol = msgPtr->_connData._sock._self->ai_protocol; } if(remoteAddr) { if ((strlen(remoteAddr->nodeID) == 0) || (strlen(remoteAddr->appID) == 0)) return INVALID_ADDR; hints.ai_family = AF_UNSPEC; hints.ai_socktype = sockType; hints.ai_flags = AI_NUMERICSERV; rc = getaddrinfo(remoteAddr->nodeID, remoteAddr->appID, &hints, &msgPtr->_connData._sock._peer); if (rc != 0) { // printf("%s", gai_strerror(rc)); return ADDRINFO_FAIL; } sockType = msgPtr->_connData._sock._peer->ai_socktype; family = msgPtr->_connData._sock._peer->ai_family; protocol = msgPtr->_connData._sock._peer->ai_protocol; } rc = socket(family, sockType, protocol); if (rc == -1) return errno2EC (errno); msgPtr->_connData._sock._sockFD = rc; } else { /*Posix message queue*/ mqd_t rc=0; SET_ZERO(msgPtr->_connData._mq._filename); if(selfAddr) { if ((strlen(selfAddr->nodeID) == 0) || (strlen(selfAddr->appID) == 0)) return INVALID_ADDR; strncpy(msgPtr->_connData._mq._filename, "/", 1); strncat(msgPtr->_connData._mq._filename, selfAddr->nodeID, NODE_ID_SIZE); strncat(msgPtr->_connData._mq._filename, selfAddr->appID, APP_ID_SIZE); rc = mq_open(msgPtr->_connData._mq._filename, O_RDWR|O_CREAT|O_EXCL, 0777, 0); if (rc == -1) return errno2EC (errno); } if(remoteAddr) { if ((strlen(remoteAddr->nodeID) == 0) || (strlen(remoteAddr->appID) == 0)) return INVALID_ADDR; strncpy(msgPtr->_connData._mq._filename, "/", 1); strncat(msgPtr->_connData._mq._filename, remoteAddr->nodeID, NODE_ID_SIZE); strncat(msgPtr->_connData._mq._filename, remoteAddr->appID, APP_ID_SIZE); rc = mq_open(msgPtr->_connData._mq._filename, O_RDWR); if (rc == -1) return errno2EC (errno); } msgPtr->_connData._mq._mqFD = rc; } retVal = bs_fmodInit (&msgPtr->_fObj, msgPtr->_mObj); if(retVal == SUCCESS) { if (type != MSG_PMSGQ) { retVal = bs_fObjectify(msgPtr->_connData._sock._sockFD, msgPtr->_fObj); } else { retVal = bs_fObjectify(msgPtr->_connData._mq._mqFD, msgPtr->_fObj); } if(retVal != SUCCESS) { bs_fmodFin(&msgPtr->_fObj, msgPtr->_mObj); } } if(msgPtr->_fObj) retVal = OBJECTIFY_FAIL; return retVal; }