Example #1
0
PUBLIC void socketDeleteHandler(int sid)
{
    WebsSocket    *sp;

    if ((sp = socketPtr(sid)) == NULL) {
        return;
    }
    sp->handler = NULL;
    socketRegisterInterest(sid, 0);
}
Example #2
0
void socketFree(int sid)
{
	socket_t	*sp;
	char_t		buf[256];
	int			i;

	if ((sp = socketPtr(sid)) == NULL) {
		return;
	}

/*
 *	To close a socket, remove any registered interests, set it to
 *	non-blocking so that the recv which follows won't block, do a
 *	shutdown on it so peers on the other end will receive a FIN,
 *	then read any data not yet retrieved from the receive buffer,
 *	and finally close it.  If these steps are not all performed
 *	RESETs may be sent to the other end causing problems.
 */
	socketRegisterInterest(sp, 0);
	if (sp->sock >= 0) {
		socketSetBlock(sid, 0);
/**************************** HANHUI ***************************/
        /*
		if (shutdown(sp->sock, 1) >= 0) {
			recv(sp->sock, buf, sizeof(buf), 0);
		}
        */
        shutdown(sp->sock, SHUT_RDWR);
/**************************** HANHUI ***************************/

#if (defined (WIN) || defined (CE))
		closesocket(sp->sock);
#else
		close(sp->sock);
#endif
	}

	ringqClose(&sp->inBuf);
	ringqClose(&sp->outBuf);
	ringqClose(&sp->lineBuf);

	bfree(B_L, sp);
	socketMax = hFree((void***) &socketList, sid);

/*
 *	Calculate the new highest socket number
 */
	socketHighestFd = -1;
	for (i = 0; i < socketMax; i++) {
		if ((sp = socketList[i]) == NULL) {
			continue;
		}
		socketHighestFd = max(socketHighestFd, sp->sock);
	}
}
Example #3
0
/*
    Create a user handler for this socket. The handler called whenever there
    is an event of interest as defined by handlerMask (SOCKET_READABLE, ...)
 */
PUBLIC void socketCreateHandler(int sid, int handlerMask, SocketHandler handler, void *data)
{
    WebsSocket    *sp;

    if ((sp = socketPtr(sid)) == NULL) {
        return;
    }
    sp->handler = handler;
    sp->handler_data = data;
    socketRegisterInterest(sid, handlerMask);
}
Example #4
0
void socketCreateHandler(int sid, int handlerMask, socketHandler_t handler, 
		int data)
{
	socket_t	*sp;

	if ((sp = socketPtr(sid)) == NULL) {
		return;
	}
	sp->handler = handler;
	sp->handler_data = data;
	socketRegisterInterest(sp, handlerMask);
}
Example #5
0
static int socketEventProc(void *data, int mask)
{
	socket_t		*sp;
	ringq_t			*rq;
	int 			sid;

	sid = (int) data;

	a_assert(sid >= 0 && sid < socketMax);
	a_assert(socketList[sid]);

	if ((sp = socketPtr(sid)) == NULL) {
		return 1;
	}

/*
 *	If now writable and flushing in the background, continue flushing
 */
	if (mask & SOCKET_WRITABLE) {
		if (sp->flags & SOCKET_FLUSHING) {
			rq = &sp->outBuf;
			if (ringqLen(rq) > 0) {
				socketFlush(sp->sid);
			} else {
				sp->flags &= ~SOCKET_FLUSHING;
			}
		}
	}

/*
 *	Now invoke the users socket handler. NOTE: the handler may delete the
 *	socket, so we must be very careful after calling the handler.
 */
	if (sp->handler && (sp->handlerMask & mask)) {
		(sp->handler)(sid, mask & sp->handlerMask, sp->handler_data);
	}
	if (socketList && sid < socketMax && socketList[sid] == sp) {
		socketRegisterInterest(sp, sp->handlerMask);
	}
	return 1;
}
Example #6
0
/*
    Free a socket structure
 */
PUBLIC void socketFree(int sid)
{
    WebsSocket  *sp;
    char        buf[256];
    int         i;

    if ((sp = socketPtr(sid)) == NULL) {
        return;
    }
    /*
        To close a socket, remove any registered interests, set it to non-blocking so that the recv which follows won't
        block, do a shutdown on it so peers on the other end will receive a FIN, then read any data not yet retrieved
        from the receive buffer, and finally close it.  If these steps are not all performed RESETs may be sent to the
        other end causing problems.
     */
    socketRegisterInterest(sid, 0);
    if (sp->sock >= 0) {
        socketSetBlock(sid, 0);
        while (recv(sp->sock, buf, sizeof(buf), 0) > 0) {}
        if (shutdown(sp->sock, SHUT_RDWR) >= 0) {
            while (recv(sp->sock, buf, sizeof(buf), 0) > 0) {}
        }
        closesocket(sp->sock);
    }
    wfree(sp->ip);
    wfree(sp);
    socketMax = wfreeHandle(&socketList, sid);
    /*
        Calculate the new highest socket number
     */
    socketHighestFd = -1;
    for (i = 0; i < socketMax; i++) {
        if ((sp = socketList[i]) == NULL) {
            continue;
        } 
        socketHighestFd = max(socketHighestFd, sp->sock);
    }
}
Example #7
0
int socketFlush(int sid)
{
	socket_t	*sp;
	ringq_t		*rq;
	int			len, bytesWritten, errCode;

	if ((sp = socketPtr(sid)) == NULL) {
		return -1;
	}
	rq = &sp->outBuf;

/*
 *	Set the background flushing flag which socketEventProc will check to
 *	continue the flush.
 */
	if (! (sp->flags & SOCKET_BLOCK)) {
		sp->flags |= SOCKET_FLUSHING;
	}

/*
 *	Break from loop if not blocking after initiating output. If we are blocking
 *	we wait for a write event.
 */
	while (ringqLen(rq) > 0) {
		len = ringqGetBlkMax(&sp->outBuf);
		bytesWritten = socketDoOutput(sp, (char*) rq->servp, len, &errCode);
		if (bytesWritten < 0) {
			if (errCode == EINTR) {
				continue;
			} else if (errCode == EWOULDBLOCK || errCode == EAGAIN) {
#if (defined (WIN) || defined (CE))
				if (sp->flags & SOCKET_BLOCK) {
					int		errCode;
					if (! socketWaitForEvent(sp,  FD_WRITE | SOCKET_WRITABLE,
						&errCode)) {
						return -1;
					}
					continue;
				} 
#endif
/*
 *				Ensure we get a FD_WRITE message when the socket can absorb
 *				more data (non-blocking only.) Store the user's mask if we
 *				haven't done it already.
 */
				if (sp->saveMask < 0 ) {
					sp->saveMask = sp->handlerMask;
					socketRegisterInterest(sp, 
					sp->handlerMask | SOCKET_WRITABLE);
				}
				return 0;
			}
			return -1;
		}
		ringqGetBlkAdj(rq, bytesWritten);
	}
/*
 *	If the buffer is empty, reset the ringq pointers to point to the start
 *	of the buffer. This is essential to ensure that datagrams get written
 *	in one single I/O operation.
 */
	if (ringqLen(rq) == 0) {
		ringqFlush(rq);
	}
/*
 *	Restore the users mask if it was saved by the non-blocking code above.
 *	Note: saveMask = -1 if empty. socketRegisterInterest will set handlerMask
 */
	if (sp->saveMask >= 0) {
		socketRegisterInterest(sp, sp->saveMask);
		sp->saveMask = -1;
	}
	sp->flags &= ~SOCKET_FLUSHING;
	return 0;
}