Пример #1
0
NL_EXP NLboolean NL_APIENTRY nlMutexDestroy(NLmutex *mutex)
{
	if(mutex == NULL)
	{
		nlSetError(NL_NULL_POINTER);
		return NL_FALSE;
	}
	if(*mutex == NULL)
	{
		nlSetError(NL_NULL_POINTER);
		return NL_FALSE;
	}
    else
    {
        NLmutex mx = *mutex;
#ifdef NL_WIN_THREADS
        /* native Windows */
        DeleteCriticalSection(&mx->mutex);
#else
        /* POSIX */
        (void)pthread_mutex_destroy((pthread_mutex_t *)&mx->mutex);
#endif
    }
    free(*mutex);
    *mutex = NULL;
    return NL_TRUE;
}
Пример #2
0
Файл: group.c Проект: Andais/dmz
NLboolean nlGroupGetSocketsINT(NLint group, NLsocket *socket, NLint *number)
{
    NLint       realgroup = group - NL_FIRST_GROUP;
    NLint       len, i;
    nl_group_t  *pgroup = NULL;

    if(socket == NULL || number == NULL)
    {
        nlSetError(NL_NULL_POINTER);
        return NL_FALSE;
    }
    if(groups == NULL)
    {
        nlSetError(NL_NO_NETWORK);
        return NL_FALSE;
    }
    if(realgroup < 0)
    {
        nlSetError(NL_INVALID_GROUP);
        *number = 0;
        return NL_FALSE;
    }
    pgroup = groups[realgroup];
	len = *number;
    if(len > pgroup->numsockets)
    {
        len = pgroup->numsockets;
    }
    for(i=0;i<len;i++)
    {
        socket[i] = pgroup->sockets[i];
    }
    *number = len;
    return NL_TRUE;
}
Пример #3
0
NL_EXP NLboolean NL_APIENTRY nlCondInit(NLcond *cond)
{
	if(cond == NULL)
	{
		nlSetError(NL_NULL_POINTER);
		return NL_FALSE;
	}
    else
    {
#ifdef NL_WIN_THREADS
        NLcond cv = NULL;

        cv = (NLcond)malloc(sizeof(struct nl_cond_t));
        if(cv == NULL)
        {
		    nlSetError(NL_OUT_OF_MEMORY);
            return NL_FALSE;
        }
        cv->events_[SIGNAL] = CreateEvent(NULL, FALSE, FALSE, NULL);
        cv->events_[BROADCAST] = CreateEvent(NULL, TRUE, FALSE, NULL);
#else
        int         result;
        NLcond   cv = NULL;

        cv = (NLcond)malloc(sizeof(struct nl_cond_t));
        if(cv == NULL)
        {
		    nlSetError(NL_OUT_OF_MEMORY);
            return NL_FALSE;
        }

        result = pthread_cond_init((pthread_cond_t *)&cv->cond, NULL);
        if(result != 0)
        {
            free(cv);
#ifdef WINDOWS_APP
            SetLastError((DWORD)result);
#endif
            nlSetError(NL_SYSTEM_ERROR);
            return NL_FALSE;
        }
        result = pthread_mutex_init((pthread_mutex_t *)&cv->mutex, NULL);
        if(result != 0)
        {
            (void)pthread_cond_destroy((pthread_cond_t *)&cv->cond);
            free(cv);
#ifdef WINDOWS_APP
            SetLastError((DWORD)result);
#endif
            nlSetError(NL_SYSTEM_ERROR);
            return NL_FALSE;
        }
#endif
        *cond = cv;
    }
    return NL_TRUE;
}
Пример #4
0
NL_EXP NLboolean NL_APIENTRY nlMutexLock(NLmutex *mutex)
{
	if(mutex == NULL)
	{
		nlSetError(NL_NULL_POINTER);
		return NL_FALSE;
	}
	if(*mutex == NULL)
	{
		nlSetError(NL_NULL_POINTER);
		return NL_FALSE;
	}
    else
    {
        NLmutex mx = *mutex;
#ifdef NL_WIN_THREADS
        DWORD threadid = GetCurrentThreadId();

        /* native Windows */
        /* this call will not stop recursion on a single thread */
        EnterCriticalSection(&mx->mutex);
        /* check for recursion */
        if(mx->thread == threadid)
        {
		    nlSetError(NL_MUTEX_RECURSION);
            /* must call LeaveCriticalSection for each EnterCriticalSection */
            /* so this nullifies the above call to EnterCriticalSection*/
            LeaveCriticalSection(&mx->mutex);
		    return NL_FALSE;
        }
        else
        {
            mx->thread = threadid;
        }
#else
        int result;

        /* POSIX */
        result = pthread_mutex_lock((pthread_mutex_t *)&mx->mutex);
        if(result == EDEADLK)
        {
		    nlSetError(NL_MUTEX_RECURSION);
		    return NL_FALSE;
        }
        else if(result != 0)
        {
#ifdef WINDOWS_APP
            SetLastError((DWORD)result);
#endif
		    nlSetError(NL_SYSTEM_ERROR);
            return NL_FALSE;
        }
#endif
    }
    return NL_TRUE;
}
Пример #5
0
NL_EXP NLboolean NL_APIENTRY nlMutexInit(NLmutex *mutex)
{
	if(mutex == NULL)
	{
		nlSetError(NL_NULL_POINTER);
		return NL_FALSE;
	}
    else
    {
        NLmutex mx;
#ifdef NL_WIN_THREADS
        /* native Windows */

        mx = (NLmutex)malloc(sizeof(struct nl_mutex_t));
	    if(mx == NULL)
	    {
		    nlSetError(NL_OUT_OF_MEMORY);
            return NL_FALSE;
	    }
        InitializeCriticalSection(&mx->mutex);
        mx->thread = 0;
#else
        /* POSIX */
        pthread_mutexattr_t attr;
        int                 result;

        mx = (NLmutex)malloc(sizeof(struct nl_mutex_t));
	    if(mx == NULL)
	    {
		    nlSetError(NL_OUT_OF_MEMORY);
            return NL_FALSE;
	    }
        (void)pthread_mutexattr_init(&attr);
#if defined Macintosh
        /* GUSI is not fully POSIX compliant, and does not define PTHREAD_MUTEX_ERRORCHECK */
        (void)pthread_mutexattr_settype(&attr, NULL);
#else
        (void)pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
#endif
        result = pthread_mutex_init((pthread_mutex_t *)&mx->mutex, &attr);
        (void)pthread_mutexattr_destroy(&attr);
        if(result != 0)
        {
#ifdef WINDOWS_APP
            SetLastError((DWORD)result);
#endif
		    nlSetError(NL_SYSTEM_ERROR);
            return NL_FALSE;
        }
#endif
        *mutex = mx;
    }
    return NL_TRUE;
}
Пример #6
0
NLboolean loopback_Connect(NLsocket socket, NLaddress *address)
{
    nl_socket_t *sock = nlSockets[socket];
    NLushort    port;
    NLint       numsockets = NL_MAX_GROUP_SOCKETS;
    NLsocket    temp[NL_MAX_GROUP_SOCKETS];

    /* no need to connect a broadcast socket */
    if(sock->type == NL_BROADCAST)
    {
        nlSetError(NL_WRONG_TYPE);
    }
    port = loopback_GetPortFromAddr(address);
    /* make sure socket is not already connected */
    if(sock->connected == NL_TRUE || sock->connecting == NL_TRUE)
    {
        nlSetError(NL_CON_REFUSED);
        return NL_FALSE;
    }
    nlGroupGetSockets(loopgroup, (NLint *)&temp, &numsockets);
    if(numsockets <= 0)
    {
        return NL_FALSE;
    }
    while(numsockets-- > 0)
    {
        nl_socket_t *othersock = nlSockets[temp[numsockets]];

        if(sock->type == othersock->type && port == othersock->localport
            && othersock->listen == NL_TRUE && othersock->connected == NL_FALSE
            && othersock->connecting == NL_FALSE)
        {
            /* we found the right socket, so connect */
            NLint i;

            for(i=0;i<NL_MAX_ACCEPT;i++)
            {
                if(othersock->accept[i] == NL_INVALID)
                {
                    othersock->accept[i] = socket;
                    sock->connecting = NL_TRUE;
                    sock->consock = temp[numsockets];
                    return NL_TRUE;
                }
            }
        }
    }
    nlSetError(NL_CON_REFUSED);
    return NL_FALSE;
}
Пример #7
0
Файл: group.c Проект: Andais/dmz
SOCKET nlGroupGetFdset(NLint group, fd_set *fd)
{
    NLint       realgroup = group - NL_FIRST_GROUP;
    nl_group_t  *pgroup = NULL;

    if(groups == NULL)
    {
        nlSetError(NL_NO_NETWORK);
        return INVALID_SOCKET;
    }
    if(realgroup < 0)
    {
        nlSetError(NL_INVALID_GROUP);
        return INVALID_SOCKET;
    }
    pgroup = groups[realgroup];
    if(pgroup == NULL)
    {
        nlSetError(NL_INVALID_GROUP);
        return INVALID_SOCKET;
    }
    /* if fdset is NULL, then create it */
    if(pgroup->fdset == NULL)
    {
        int     i;
        SOCKET  realsock;
        /* create the fd_set */
        pgroup->fdset = (fd_set *)malloc(sizeof(fd_set));
        if(pgroup->fdset == NULL)
        {
            (void)nlMutexUnlock(&grouplock);
            nlSetError(NL_OUT_OF_MEMORY);
            return INVALID_SOCKET;
        }
        FD_ZERO(pgroup->fdset);
        pgroup->highest = 0;
        for(i=0;i<pgroup->numsockets;i++)
        {
            realsock = (SOCKET)nlSockets[pgroup->sockets[i]]->realsocket;
            FD_SET(realsock, pgroup->fdset);
            if(pgroup->highest < realsock + 1)
            {
                pgroup->highest = realsock + 1;
            }
        }
    }
    memcpy(fd, pgroup->fdset, sizeof(fd_set));

    return pgroup->highest;
}
Пример #8
0
NL_EXP NLboolean NL_APIENTRY nlMutexUnlock(NLmutex *mutex)
{
	if(mutex == NULL)
	{
		nlSetError(NL_NULL_POINTER);
		return NL_FALSE;
	}
	if(*mutex == NULL)
	{
		nlSetError(NL_NULL_POINTER);
		return NL_FALSE;
	}
    else
    {
        NLmutex mx = *mutex;
#ifdef NL_WIN_THREADS
        DWORD threadid = GetCurrentThreadId();

        /* native Windows */
        if((mx->thread == 0) ||(mx->thread != threadid))
        {
		    nlSetError(NL_MUTEX_OWNER);
		    return NL_FALSE;
        }
        mx->thread = 0;
        LeaveCriticalSection(&mx->mutex);
#else
        int result;

        /* POSIX */
        result = pthread_mutex_unlock((pthread_mutex_t *)&mx->mutex);
        if(result == EPERM)
        {
		    nlSetError(NL_MUTEX_OWNER);
		    return NL_FALSE;
        }
        else if(result != 0)
        {
#ifdef WINDOWS_APP
            SetLastError((DWORD)result);
#endif
		    nlSetError(NL_SYSTEM_ERROR);
            return NL_FALSE;
        }
#endif
    }
    return NL_TRUE;
}
Пример #9
0
NLsocket loopback_AcceptConnection(NLsocket socket)
{
    nl_socket_t *sock = nlSockets[socket];
    NLint       i;

    if(sock->listen == NL_FALSE)
    {
        nlSetError(NL_NOT_LISTEN);
        return NL_INVALID;
    }
    /* look for a valid socket */
    for(i=0;i<NL_MAX_ACCEPT;i++)
    {
        if(sock->accept[i] != NL_INVALID)
        {
            NLsocket    newsocket = loopback_Open(0, sock->type);
            NLsocket    osock = sock->accept[i];
            nl_socket_t *othersock = nlSockets[osock];

            sock->accept[i] = NL_INVALID;
            if(newsocket != NL_INVALID)
            {
                nl_socket_t *newsock = nlSockets[newsocket];

                nlLockSocket(osock, NL_BOTH);
                /* do the connecting */
                newsock->consock = osock;
                newsock->remoteport = othersock->localport;
                othersock->consock = newsocket;
                othersock->remoteport = newsock->localport;
                newsock->connected = NL_TRUE;
                othersock->connected = NL_TRUE;
                othersock->connecting = NL_FALSE;
                loopback_SetAddrPort(&othersock->address, othersock->remoteport);
                loopback_SetAddrPort(&newsock->address, newsock->remoteport);
                nlUnlockSocket(osock, NL_BOTH);
                return newsocket;
            }
        }
    }
    nlSetError(NL_NO_PENDING);
    return NL_INVALID;
}
Пример #10
0
NLint loopback_Read(NLsocket socket, NLvoid *buffer, NLint nbytes)
{
    nl_socket_t *sock = nlSockets[socket];
    NLint       len = sock->inlen[sock->nextinused];
    NLint       c = 0;
    NLushort    port;

    if(len > 0)
    {
        if(len > nbytes)
        {
            nlSetError(NL_BUFFER_SIZE);
            return NL_INVALID;
        }
        if(sock->connecting == NL_TRUE)
        {
            nlSetError(NL_CON_PENDING);
            return NL_INVALID;
        }
        /* get the port number */
        readShort(sock->inpacket[sock->nextinused], c, port);
        loopback_SetAddrPort(&sock->address, port);
        /* copy the packet */
        memcpy(buffer, sock->inpacket[sock->nextinused] + 2, (size_t)len);
        /* zero out length and set up for next packet */
        sock->inlen[sock->nextinused] = 0;
        sock->nextinused++;
        if(sock->nextinused >= NL_NUM_PACKETS)
        {
            sock->nextinused = 0;
        }
    }
    /* check for broken connection */
    if(sock->connected == NL_TRUE && sock->consock == NL_INVALID)
    {
        nlSetError(NL_CON_TERM);
        return NL_INVALID;
    }
    return len;
}
Пример #11
0
void loopback_Hint(NLenum name, NLint arg)
{
    switch (name) {

    case NL_REUSE_ADDRESS:
        reuseaddress = (NLboolean)(arg != 0 ? NL_TRUE : NL_FALSE);
        break;

    default:
        nlSetError(NL_INVALID_ENUM);
        break;
    }
}
Пример #12
0
Файл: group.c Проект: Andais/dmz
NL_EXP NLboolean NL_APIENTRY nlGroupDestroy(NLint group)
{
    NLint   realgroup = group - NL_FIRST_GROUP;

    if(groups == NULL)
    {
        nlSetError(NL_NO_NETWORK);
        return NL_FALSE;
    }
    if(realgroup < 0)
    {
        nlSetError(NL_INVALID_GROUP);
        return NL_FALSE;
    }
    if(nlMutexLock(&grouplock) == NL_FALSE)
    {
        return NL_FALSE;
    }
    if(groups[realgroup] != NULL)
    {
        if(groups[realgroup]->fdset != NULL)
        {
            free(groups[realgroup]->fdset);
        }
        if(groups[realgroup]->sockets != NULL)
        {
            free(groups[realgroup]->sockets);
        }
        free(groups[realgroup]);
        groups[realgroup] = NULL;
        nlnumgroups--;
    }
    if(nlMutexUnlock(&grouplock) == NL_FALSE)
    {
        return NL_FALSE;
    }
    return NL_TRUE;
}
Пример #13
0
NLboolean loopback_Listen(NLsocket socket)
{
    nl_socket_t *sock = nlSockets[socket];
    NLint       i = NL_MAX_ACCEPT;

    if(sock->type == NL_BROADCAST)
    {
        nlSetError(NL_WRONG_TYPE);
        return NL_FALSE;
    }
    sock->listen = NL_TRUE;
    while(i-- > 0)
    {
        sock->accept[i] = NL_INVALID;
    }
    return NL_TRUE;
}
Пример #14
0
Файл: group.c Проект: Andais/dmz
NLboolean nlGroupInit(void)
{
    if(groups == NULL)
    {
        groups = (nl_group_t **)malloc(NL_MAX_GROUPS * sizeof(nl_group_t *));
    }
    if(groups == NULL)
    {
        nlSetError(NL_OUT_OF_MEMORY);
        return NL_FALSE;
    }
    memset(groups, 0, NL_MAX_GROUPS * sizeof(nl_group_t *));
    if(nlMutexInit(&grouplock) == NL_FALSE)
    {
        /* error code is already set */
        return NL_FALSE;
    }
    return NL_TRUE;
}
Пример #15
0
// copied from HawkNL sock.c and modified to not use nlStringToNetAddr
static bool GetAddrFromNameAsync_Internal(const NLchar* name, NLaddress* address) {
	struct hostent *hostentry;
    NLushort    port = 0;
    int			pos;
    NLbyte      temp[NL_MAX_STRING_LENGTH];
	
#ifdef _UNICODE
    /* convert from wide char string to multibyte char string */
    (void)wcstombs(temp, (const NLchar *)name, NL_MAX_STRING_LENGTH);
#else
    strncpy(temp, name, NL_MAX_STRING_LENGTH);
#endif
    temp[NL_MAX_STRING_LENGTH - 1] = (NLbyte)'\0';
    pos = (int)strcspn(temp, (const char *)":");
    if(pos > 0)
    {
        NLbyte      *p = &temp[pos+1];
		
        temp[pos] = (NLbyte)'\0';
        (void)sscanf(p, "%hu", &port);
    }
    hostentry = gethostbyname((const char *)temp);
	
    if(hostentry != NULL)
    {
        ((struct sockaddr_in *)address)->sin_family = AF_INET;
        ((struct sockaddr_in *)address)->sin_port = htons(port);
        ((struct sockaddr_in *)address)->sin_addr.s_addr = *(NLulong *)hostentry->h_addr_list[0];
        address->valid = NL_TRUE;
    }
    else
    {
        ((struct sockaddr_in *)address)->sin_family = AF_INET;
        ((struct sockaddr_in *)address)->sin_addr.s_addr = INADDR_NONE;
        ((struct sockaddr_in *)address)->sin_port = 0;
        nlSetError(NL_SYSTEM_ERROR);
        return false;
    }
    return true;
}
Пример #16
0
Файл: group.c Проект: Andais/dmz
NL_EXP NLboolean NL_APIENTRY nlGroupAddSocket(NLint group, NLsocket socket)
{
    NLint       realgroup = group - NL_FIRST_GROUP;
    NLint       i;
    nl_group_t  *pgroup = NULL;

    if(groups == NULL)
    {
        nlSetError(NL_NO_NETWORK);
        return NL_FALSE;
    }
    if(realgroup < 0)
    {
        nlSetError(NL_INVALID_GROUP);
        return NL_FALSE;
    }

    /* add the socket to the group */
    if(nlMutexLock(&grouplock) == NL_FALSE)
    {
        return NL_FALSE;
    }
    pgroup = groups[realgroup];
    /* allocate more sockets as needed */
    if(pgroup->numsockets == pgroup->maxsockets)
    {
        NLint       oldmax = pgroup->maxsockets;
        NLint       j;
        NLsocket    *newsockets;

        if(oldmax == NL_MAX_GROUP_SOCKETS)
        {
            (void)nlMutexUnlock(&grouplock);
            nlSetError(NL_OUT_OF_GROUP_SOCKETS);
            return NL_FALSE;
        }
        pgroup->maxsockets *= 2;
        if(pgroup->maxsockets > NL_MAX_GROUP_SOCKETS)
        {
            pgroup->maxsockets = NL_MAX_GROUP_SOCKETS;
        }
        if((newsockets = (NLsocket *)realloc(pgroup->sockets, pgroup->maxsockets * sizeof(NLsocket *))) == NULL)
        {
            pgroup->maxsockets = oldmax;
            (void)nlMutexUnlock(&grouplock);
            nlSetError(NL_OUT_OF_MEMORY);
            return NL_FALSE;
        }
        /* set the new sockets to -1 */
        for(j=oldmax;j<pgroup->maxsockets;j++)
        {
            newsockets[j] = -1;
        }
        pgroup->sockets = newsockets;
    }

    for(i=0;i<pgroup->maxsockets;i++)
    {
        if(pgroup->sockets[i] == -1)
        {
            pgroup->sockets[i] = socket;
            if(pgroup->fdset != NULL)
            {
                SOCKET realsock;

                /* make sure the socket is valid */
                if(nlIsValidSocket(socket) == NL_FALSE)
                {
                    (void)nlMutexUnlock(&grouplock);
                    nlSetError(NL_INVALID_SOCKET);
                    return NL_FALSE;
                }
                realsock = (SOCKET)nlSockets[socket]->realsocket;
                FD_SET(realsock, pgroup->fdset);
                if(pgroup->highest < realsock + 1)
                {
                    pgroup->highest = realsock + 1;
                }
            }
            break;
        }
    }
    if(i == pgroup->maxsockets)
    {
        (void)nlMutexUnlock(&grouplock);
        nlSetError(NL_OUT_OF_GROUP_SOCKETS);
        return NL_FALSE;
    }
    pgroup->numsockets++;
    if(nlMutexUnlock(&grouplock) == NL_FALSE)
    {
        return NL_FALSE;
    }
    return NL_TRUE;
}
Пример #17
0
Файл: group.c Проект: Andais/dmz
NL_EXP NLint NL_APIENTRY nlGroupCreate(void)
{
    NLint       newgroup = NL_INVALID;
    nl_group_t  *pgroup = NULL;

    if(groups == NULL)
    {
        nlSetError(NL_NO_NETWORK);
        return NL_INVALID;
    }
    if(nlMutexLock(&grouplock) == NL_FALSE)
    {
        return NL_INVALID;
    }
    if(nlnumgroups == NL_MAX_GROUPS)
    {
        (void)nlMutexUnlock(&grouplock);
        nlSetError(NL_OUT_OF_GROUPS);
        return NL_INVALID;
    }
    /* get a group number */
    if(nlnumgroups == nlnextgroup)
    {
        /* do not increment nlnextgroup here, wait in case of malloc failure */
        newgroup = nlnextgroup + 1;
    }
    else
    /* there is an open group slot somewhere below nlnextgroup */
    {
        NLint   i;

        for(i=0;i<nlnextgroup;i++)
        {
            if(groups[i] == NULL)
            {
                /* found an open group slot */
                newgroup = i;
            }
        }
        /* let's check just to make sure we did find a group */
        if(newgroup == NL_INVALID)
        {
            (void)nlMutexUnlock(&grouplock);
            nlSetError(NL_OUT_OF_MEMORY);
            return NL_INVALID;
        }
    }
    /* allocate the memory */
    pgroup = (nl_group_t *)malloc((size_t)(sizeof(nl_group_t)));
    if(pgroup == NULL)
    {
        (void)nlMutexUnlock(&grouplock);
        nlSetError(NL_OUT_OF_MEMORY);
        return NL_INVALID;
    }
    else
    {
        NLint   i;

        pgroup->sockets = (NLsocket *)malloc(NL_MIN_SOCKETS * sizeof(NLsocket *));
        if(pgroup->sockets == NULL)
        {
            free(pgroup);
            (void)nlMutexUnlock(&grouplock);
            nlSetError(NL_OUT_OF_MEMORY);
            return NL_INVALID;
        }
        pgroup->maxsockets = NL_MIN_SOCKETS;
        /* fill with -1, since 0 is a valid socket number */
        for(i=0;i<pgroup->maxsockets;i++)
        {
            pgroup->sockets[i] =  -1;
        }
        pgroup->numsockets = 0;
        pgroup->fdset = NULL;
        pgroup->highest = 0;
        groups[newgroup] = pgroup;
    }

    nlnumgroups++;
    if(nlnumgroups == newgroup)
    {
        nlnextgroup = nlnumgroups;
    }
    if(nlMutexUnlock(&grouplock) == NL_FALSE)
    {
        return NL_INVALID;
    }
    /* adjust the group number */
    return (newgroup + NL_FIRST_GROUP);
}
Пример #18
0
void ResetSocketError()  {
	if (!bNetworkInited)
		return;
	
	nlSetError(NL_NO_ERROR);
}
Пример #19
0
NL_EXP NLboolean NL_APIENTRY nlCondWait(NLcond *cond, NLint timeout)
{
    if(cond == NULL)
    {
		nlSetError(NL_NULL_POINTER);
		return NL_FALSE;
    }
    if(*cond == NULL)
    {
		nlSetError(NL_NULL_POINTER);
		return NL_FALSE;
    }
    if(timeout <= 0)
    {
        NLcond cv = *cond;

#ifdef NL_WIN_THREADS
        DWORD result;

        result = WaitForMultipleObjects (2,cv->events_, FALSE, INFINITE);
        if(result == WAIT_FAILED)
        {
            nlSetError(NL_SYSTEM_ERROR);
            return NL_FALSE;
        }
#else
        int result = 0;

        (void)pthread_mutex_lock((pthread_mutex_t *)&cv->mutex);
        result = pthread_cond_wait((pthread_cond_t *)&cv->cond, (pthread_mutex_t *)&cv->mutex);
        if(result != 0)
        {
#ifdef WINDOWS_APP
            SetLastError((DWORD)result);
#endif
            nlSetError(NL_SYSTEM_ERROR);
            return NL_FALSE;
        }
        (void)pthread_mutex_unlock((pthread_mutex_t *)&cv->mutex);
#endif
    }
    else
    {
        NLcond cv = *cond;

#ifdef NL_WIN_THREADS
        DWORD result;

        result = WaitForMultipleObjects (2, cv->events_, FALSE, (DWORD)timeout);
        if(result == WAIT_FAILED)
        {
            nlSetError(NL_SYSTEM_ERROR);
            return NL_FALSE;
        }
        else if(result == WAIT_TIMEOUT)
        {
            nlSetError(NL_TIMED_OUT);
            return NL_FALSE;
        }
    }
#else
        int                 result = 0;
        struct timespec     tv;
        NLtime              t;
        NLlong              ms;

        /* convert timeout to an absolute time */
        (void)nlTime(&t);
        ms = t.mseconds + timeout;
        tv.tv_sec = t.seconds + (ms / 1000);
        tv.tv_nsec = (ms % 1000) * 1000;

        (void)pthread_mutex_lock((pthread_mutex_t *)&cv->mutex);
        result = pthread_cond_timedwait((pthread_cond_t *)&cv->cond,
                                            (pthread_mutex_t *)&cv->mutex, &tv);
        if(result == ETIMEDOUT)
        {
            nlSetError(NL_TIMED_OUT);
            (void)pthread_mutex_unlock((pthread_mutex_t *)&cv->mutex);
            return NL_FALSE;
        }
        else if(result != 0)
        {
#ifdef WINDOWS_APP
            SetLastError((DWORD)result);
#endif
            nlSetError(NL_SYSTEM_ERROR);
            return NL_FALSE;
        }
        (void)pthread_mutex_unlock((pthread_mutex_t *)&cv->mutex);
    }
Пример #20
0
NLint loopback_PollGroup(NLint group, NLenum name, NLsocket *sockets, NLint number, NLint timeout)
{
    NLint           count = 0;
    NLint           numsockets = NL_MAX_GROUP_SOCKETS;
    NLsocket        temp[NL_MAX_GROUP_SOCKETS];

    nlGroupGetSockets(group, (NLint *)&temp, &numsockets);
    if(numsockets < 0)
    {
        /* any error is set by nlGroupGetSockets */
        return NL_INVALID;
    }
    if(numsockets == 0)
    {
        return 0;
    }

    switch(name) {

    case NL_READ_STATUS:
        {
            NLint   i = 0;

            while(numsockets-- > 0)
            {
                /* check for a packet */
                nl_socket_t *sock;

                if(nlIsValidSocket(temp[i]) != NL_TRUE)
                {
                    nlSetError(NL_INVALID_SOCKET);
                    return NL_INVALID;
                }
                sock = nlSockets[temp[i]];

                if(sock->inlen[sock->nextinused] > 0)
                {
                    *sockets = temp[i];
                    sockets++;
                    count++;
                    if(count > number)
                    {
                        nlSetError(NL_BUFFER_SIZE);
                        return NL_INVALID;
                    }
                }
                i++;
            }
        }
        break;

    case NL_WRITE_STATUS:
        {
            NLint   i = 0;

            while(numsockets-- > 0)
            {
                nl_socket_t *sock;

                if(nlIsValidSocket(temp[i]) != NL_TRUE)
                {
                    nlSetError(NL_INVALID_SOCKET);
                    return NL_INVALID;
                }
                sock = nlSockets[temp[i]];

                /* check for a free packet if reliable and connected */
                if((sock->type == NL_RELIABLE || sock->type == NL_RELIABLE_PACKETS)
                    && (sock->connecting == NL_TRUE || sock->connected == NL_TRUE))
                {
                    nl_socket_t *othersock = nlSockets[sock->consock];

                    if(othersock->nextinfree == NL_INVALID)
                    {
                        continue;
                    }
                }
                /* add the socket to the list */
                *sockets = temp[i];
                sockets++;
                count++;
                if(count > number)
                {
                    nlSetError(NL_BUFFER_SIZE);
                    return NL_INVALID;
                }
                i++;
            }
        }
        break;

    default:
        nlSetError(NL_INVALID_ENUM);
        return NL_INVALID;
    }
    return count;
}
Пример #21
0
NLint loopback_Write(NLsocket socket, NLvoid *buffer, NLint nbytes)
{
    nl_socket_t *sock = nlSockets[socket];
    nl_socket_t *othersock;
    NLint       s[NL_MAX_GROUP_SOCKETS];
    NLint       number = NL_MAX_GROUP_SOCKETS;
    NLint       i;
    NLint       count;

    switch (sock->type) {

    case NL_RELIABLE:
    case NL_UNRELIABLE:
    case NL_RELIABLE_PACKETS:
    default:
        {
            if(sock->connected == NL_TRUE)
            {
                /* check for broken connection */
                if(sock->consock == NL_INVALID)
                {
                    nlSetError(NL_CON_TERM);
                    return NL_INVALID;
                }
                count = loopback_WritePacket(sock->consock, buffer, nbytes, sock->localport);
            }
            else if(sock->connecting == NL_TRUE)
            {
                nlSetError(NL_CON_PENDING);
                return NL_INVALID;
            }
            count = nbytes;
            nlGroupGetSockets(loopgroup, s, &number);
            for(i=0;i<number;i++)
            {
                if(nlIsValidSocket(s[i]) == NL_TRUE)
                {
                    othersock = nlSockets[s[i]];

                    if(sock->remoteport == othersock->localport &&
                        othersock->connected == NL_FALSE &&
                        sock->type == othersock->type)
                    {
                        (void)loopback_WritePacket(s[i], buffer, nbytes, sock->localport);
                    }
                }
            }
        }
        break;
    case NL_BROADCAST:
        {
            count = nbytes;
            nlGroupGetSockets(loopgroup, s, &number);
            for(i=0;i<number;i++)
            {
                if(nlIsValidSocket(s[i]) == NL_TRUE)
                {
                    othersock = nlSockets[s[i]];

                    if(sock->localport == othersock->localport &&
                        sock->type == othersock->type)
                    {
                        (void)loopback_WritePacket(s[i], buffer, nbytes, sock->localport);
                    }
                }
            }
        }
    }

    return count;
}
Пример #22
0
// modified sock_Write of sock.c from HawkNL
// returns true if socket is connected and data could be send
static bool nlUpdateState(NLsocket socket)
{
	if(nlIsValidSocket(socket) != NL_TRUE) return false;
	
	struct Unlocker {
		NLsocket socket;
		~Unlocker() {
			nlUnlockSocket(socket, NL_BOTH);
		}
		Unlocker(NLsocket s) : socket(s) {}
	};
	
	if(nlLockSocket(socket, NL_BOTH) == NL_FALSE)
	{
		return false;
	}
	
	Unlocker unlocker(socket);
	
	nl_socket_t *sock = nlSockets[socket];
	NLint       count = 0;

	if((sock->type == NL_RELIABLE) || (sock->type == NL_RELIABLE_PACKETS)) /* TCP */
	{
		if(sock->connecting == NL_TRUE)
		{
			fd_set          fdset;
			struct timeval  t = {0,0};
			int             serrval = -1;
			socklen_t       serrsize = (socklen_t)sizeof(serrval);


			FD_ZERO(&fdset);
			FD_SET((SOCKET)sock->realsocket, &fdset);
			if(select(sock->realsocket + 1, NULL, &fdset, NULL, &t) == 1)
			{
				/* Check the socket status */
				(void)getsockopt( sock->realsocket, SOL_SOCKET, SO_ERROR, (char *)&serrval, &serrsize );
				if(serrval != 0)
				{
					if(serrval == ECONNREFUSED)
					{
						nlSetError(NL_CON_REFUSED);
					}
					else if(serrval == EINPROGRESS || serrval == EWOULDBLOCK)
					{
						nlSetError(NL_CON_PENDING);
					}
					return false;
				}
				/* the connect has completed */
				sock->connected = NL_TRUE;
				sock->connecting = NL_FALSE;
			}
			else
			{
				/* check for a failed connect */
				FD_ZERO(&fdset);
				FD_SET((SOCKET)sock->realsocket, &fdset);
				if(select(sock->realsocket + 1, NULL, NULL, &fdset, &t) == 1)
				{
					nlSetError(NL_CON_REFUSED);
				}
				else
				{
					nlSetError(NL_CON_PENDING);
				}
				return false;
			}
		}
		/* check for reliable packets */
		if(sock->type == NL_RELIABLE_PACKETS)
		{
			return true;
		}
		return true;
	}
	else /* unconnected UDP */
	{
		/* check for a non-blocking connection pending */
		if(sock->connecting == NL_TRUE)
		{
			nlSetError(NL_CON_PENDING);
			return false;
		}
		/* check for a connection error */
		if(sock->conerror == NL_TRUE)
		{
			nlSetError(NL_CON_REFUSED);
			return false;
		}
		if(sock->type == NL_BROADCAST)
		{
			((struct sockaddr_in *)&sock->addressin)->sin_addr.s_addr = INADDR_BROADCAST;
		}
		if(sock->type == NL_UDP_MULTICAST)
		{
			return true;
		}
		else if(sock->connected == NL_TRUE)
		{
			return true;
		}
		else
		{
			return true;
		}
	}
	if(count == SOCKET_ERROR)
	{
		return false;
	}
	return false;
}
Пример #23
0
Файл: group.c Проект: Andais/dmz
NL_EXP NLboolean NL_APIENTRY nlGroupDeleteSocket(NLint group, NLsocket socket)
{
    NLint       realgroup = group - NL_FIRST_GROUP;
    NLint       i;
    nl_group_t  *pgroup = NULL;

    if(groups == NULL)
    {
        nlSetError(NL_NO_NETWORK);
        return NL_FALSE;
    }
    if(realgroup < 0)
    {
        nlSetError(NL_INVALID_GROUP);
        return NL_FALSE;
    }

    /* delete the socket from the group */
    if(nlMutexLock(&grouplock) == NL_FALSE)
    {
        return NL_FALSE;
    }
    pgroup = groups[realgroup];
    for(i=0;i<pgroup->numsockets;i++)
    {
        /* check for match */
        if(pgroup->sockets[i] == socket)
            break;
    }
    if(i == pgroup->numsockets)
    {
        /* did not find the socket */
        (void)nlMutexUnlock(&grouplock);
        nlSetError(NL_SOCKET_NOT_FOUND);
        return NL_FALSE;
    }
    /* now pgroup[i] points to the socket to delete */
    /* shift all other sockets down to close the gap */
    i++;
    for(;i<pgroup->maxsockets;i++)
    {
        pgroup->sockets[i - 1] = pgroup->sockets[i];
        /* check for end of list */
        if(pgroup->sockets[i] == -1)
            break;
    }
    pgroup->numsockets--;
    if(pgroup->fdset != NULL)
    {
        /* make sure the socket is valid */
        if(nlIsValidSocket(socket) == NL_TRUE)
        {
            SOCKET realsock;

            realsock = (SOCKET)nlSockets[socket]->realsocket;
            FD_CLR(realsock, pgroup->fdset);
        }
        else
        {
            /* the socket was already closed */
            /* free the fdset so that it can be rebuilt */
            free(pgroup->fdset);
            pgroup->fdset = NULL;
            (void)nlMutexUnlock(&grouplock);
            nlSetError(NL_INVALID_SOCKET);
            return NL_FALSE;
        }
    }
    if(nlMutexUnlock(&grouplock) == NL_FALSE)
    {
        return NL_FALSE;
    }
    return NL_TRUE;
}
Пример #24
0
NLsocket loopback_Open(NLushort port, NLenum type)
{
    nl_socket_t *newsock;
    NLsocket    newsocket;
    NLint       i;
    NLushort    lport;

    switch (type) {

    case NL_RELIABLE:
    case NL_UNRELIABLE:
    case NL_RELIABLE_PACKETS:
    case NL_BROADCAST:
        break;

    default:
        nlSetError(NL_INVALID_ENUM);
        return NL_INVALID;
    }

    lport = loopback_TryPort(port, type);
    if(lport == 0)
    {
        nlSetError(NL_INVALID_PORT);
        return NL_INVALID;
    }
    newsocket = nlGetNewSocket();
    if(newsocket == NL_INVALID)
    {
        return NL_INVALID;
    }
    newsock = nlSockets[newsocket];
    newsock->type = type;
    newsock->localport = lport;
    if(type == NL_BROADCAST)
    {
        newsock->remoteport = lport;
    }

    for(i=0;i<NL_NUM_PACKETS;i++)
    {
        NLboolean err = NL_FALSE;

        /* malloc the max packet length plus two bytes for the port number */
        if((newsock->inpacket[i] = (NLbyte *)malloc((size_t)(NL_MAX_PACKET_LENGTH + 2))) == NULL)
        {
            nlSetError(NL_OUT_OF_MEMORY);
            err = NL_TRUE;
        }
        if(err == NL_TRUE)
        {
            while(i-- > 0)
            {
                free(newsock->inpacket[i]);
            }
            sock_Close(newsocket);
            return NL_INVALID;
        }
    }

    (void)nlGroupAddSocket(loopgroup, newsocket);

    return newsocket;
}
Пример #25
0
static NLint loopback_WritePacket(NLsocket to, NLvoid *buffer, NLint nbytes, NLushort fromport)
{
    nl_socket_t *sock = nlSockets[to];
    NLint       i, j;
    NLint       c = 0;

    /* check the packet size */
    if(nbytes > NL_MAX_PACKET_LENGTH)
    {
        nlSetError(NL_PACKET_SIZE);
        return NL_INVALID;
    }
    nlLockSocket(to, NL_READ);
    /* make sure we have an empty packet buffer */
    if(sock->nextinfree == NL_INVALID)
    {
        /* all buffers were filled by last write */
        /* check to see if any were emptied by a read */
        i = NL_NUM_PACKETS;
        j = sock->nextinused;

        while(i-- > 0)
        {
            if(sock->inlen[j] == 0)
            {
                /* found the first free */
                sock->nextinfree = j;
                break;
            }
            j++;
            if(j >= NL_NUM_PACKETS)
            {
                j = 0;
            }
        }
        if(sock->nextinfree == NL_INVALID)
        {
            nlUnlockSocket(to, NL_READ);
            /* none are free */
            if(sock->type == NL_RELIABLE || sock->type == NL_RELIABLE_PACKETS)
            {
                return 0;
            }
            else
            {
                /* silently fail */
                return nbytes;
            }
        }
    }
    /* write the port number */
    writeShort(sock->inpacket[sock->nextinfree], c, fromport);
    /* copy the packet buffer */
    memcpy(sock->inpacket[sock->nextinfree] + 2, buffer, (size_t)nbytes);
    sock->inlen[sock->nextinfree] = nbytes;
    sock->nextinfree++;
    if(sock->nextinfree >= NL_NUM_PACKETS)
    {
        sock->nextinfree = 0;
    }
    /* check for full packet buffers */
    if(sock->inlen[sock->nextinfree] != 0)
    {
        sock->nextinfree = NL_INVALID;
    }
    nlUnlockSocket(to, NL_READ);
    return nbytes;
}
Пример #26
0
NL_EXP NLboolean NL_APIENTRY nlTime(NLtime *t)
{
#ifdef WINDOWS_APP
    static NLboolean        needinit = NL_TRUE;
    static NLboolean        haspcounter = NL_FALSE;
    static LARGE_INTEGER    freq;
    static LARGE_INTEGER    lastcount;
    static NLtime           currenttime;

    if(t == NULL)
    {
		nlSetError(NL_NULL_POINTER);
		return NL_FALSE;
    }
    if(needinit == NL_TRUE)
    {
        if(QueryPerformanceFrequency(&freq) != 0)
        {
            if(QueryPerformanceCounter(&lastcount) != 0)
            {
                /* get the current time */
                struct mytimeb tb;

                myftime(&tb);
                currenttime.seconds = (NLlong)(tb.time);
                currenttime.useconds = (NLlong)(tb.millitm * 1000);
                haspcounter = NL_TRUE;
            }
        }
        needinit = NL_FALSE;
    }
    if(haspcounter == NL_TRUE)
    {
        LARGE_INTEGER   currentcount;
        LARGE_INTEGER   diffcount;

        (void)QueryPerformanceCounter(&currentcount);
        diffcount.QuadPart = currentcount.QuadPart - lastcount.QuadPart;
        lastcount.QuadPart = currentcount.QuadPart;
        while(diffcount.QuadPart >= freq.QuadPart)
        {
            diffcount.QuadPart -= freq.QuadPart;
            currenttime.seconds++;
        }
        currenttime.useconds += (NLlong)(diffcount.QuadPart * 1000000 / freq.QuadPart);
        if(currenttime.useconds >= 1000000)
        {
            currenttime.useconds -= 1000000;
            currenttime.seconds++;
        }
        t->seconds = currenttime.seconds;
        t->mseconds = currenttime.useconds / 1000;
        t->useconds = currenttime.useconds;
    }
    else
    {
        /* fall back to myftime */
        struct mytimeb tb;

        myftime(&tb);
        t->seconds = (NLlong)(tb.time);
        t->mseconds = (NLlong)(tb.millitm);
        t->useconds = (NLlong)(tb.millitm * 1000);
    }
#else /* !WINDOWS_APP */
    struct timeval tv;

    if(t == NULL)
    {
		nlSetError(NL_NULL_POINTER);
		return NL_FALSE;
    }
    gettimeofday(&tv, NULL);
    t->seconds = (NLlong)(tv.tv_sec);
    t->mseconds = (NLlong)(tv.tv_usec / 1000);
    t->useconds = (NLlong)(tv.tv_usec);
#endif /* !WINDOWS_APP */
    return NL_TRUE;
}