예제 #1
0
파일: lisk_ring.c 프로젝트: bugou/test
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);
}
예제 #2
0
파일: msg.c 프로젝트: plasmixs/virtcluster
/**
 * 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;
}
예제 #3
0
파일: msg.c 프로젝트: plasmixs/virtcluster
/**
 * 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;
}
예제 #4
0
파일: msg.c 프로젝트: plasmixs/virtcluster
/**
 * 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;
}
예제 #5
0
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();
}
예제 #6
0
/*
 * 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 */
}
예제 #7
0
파일: msg.c 프로젝트: plasmixs/virtcluster
/**
 * 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;
}