Пример #1
0
static int socketDoEvent(socket_t *sp)
{
	ringq_t		*rq;
	int 		sid;

	a_assert(sp);

	sid = sp->sid;
	if (sp->currentEvents & SOCKET_READABLE) {
		if (sp->flags & SOCKET_LISTENING) { 
			socketAccept(sp);
			sp->currentEvents = 0;
			return 1;
		} 

	} else {
/*
 *		If there is still read data in the buffers, trigger the read handler
 *		NOTE: this may busy spin if the read handler doesn't read the data
 */
		if (sp->handlerMask & SOCKET_READABLE && socketInputBuffered(sid) > 0) {
			sp->currentEvents |= SOCKET_READABLE;
		}
	}


/*
 *	If now writable and flushing in the background, continue flushing
 */
	if (sp->currentEvents & 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 & sp->currentEvents)) {
		(sp->handler)(sid, sp->handlerMask & sp->currentEvents, 
			sp->handler_data);
/*
 *		Make sure socket pointer is still valid, then reset the currentEvents.
 */ 
		if (socketList && sid < socketMax && socketList[sid] == sp) {
			sp->currentEvents = 0;
		}
	}
	return 1;
}
Пример #2
0
int	socketWrite(int sid, char *buf, int bufsize)
{
	socket_t	*sp;
	ringq_t		*rq;
	int			len, bytesWritten, room;

	a_assert(buf);
	a_assert(bufsize >= 0);

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

/*
 *	Loop adding as much data to the output ringq as we can absorb. Initiate a 
 *	flush when the ringq is too full and continue. Block in socketFlush if the
 *	socket is in blocking mode.
 */
	rq = &sp->outBuf;
	for (bytesWritten = 0; bufsize > 0; ) {
		if ((room = ringqPutBlkMax(rq)) == 0) {
			if (socketFlush(sid) < 0) {
				return -1;
			}
			if ((room = ringqPutBlkMax(rq)) == 0) {
				if (sp->flags & SOCKET_BLOCK) {
#if (defined (WIN) || defined (CE))
					int		errCode;
					if (! socketWaitForEvent(sp,  FD_WRITE | SOCKET_WRITABLE,
						&errCode)) {
						return -1;
					}
#endif
					continue;
				}
				break;
			}
			continue;
		}
		len = min(room, bufsize);
		ringqPutBlk(rq, (unsigned char *) buf, len);
		bytesWritten += len;
		bufsize -= len;
		buf += len;
	}
	return bytesWritten;
}
Пример #3
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;
}