void dyad_end(dyad_Stream *stream) { if (stream->state == DYAD_STATE_CLOSED) return; if (stream->writeBuffer.length > 0) { stream->state = DYAD_STATE_CLOSING; } else { dyad_close(stream); } }
static int dyad_flushWriteBuffer(dyad_Stream *stream) { stream->flags &= ~DYAD_FLAG_WRITTEN; if (stream->writeBuffer.length > 0) { /* Send data */ int size = send(stream->sockfd, stream->writeBuffer.data, stream->writeBuffer.length, 0); if (size <= 0) { if (errno == EWOULDBLOCK) { /* No more data can be written */ return 0; } else { /* Handle disconnect */ dyad_close(stream); return 0; } } if (size == stream->writeBuffer.length) { dyad_vectorClear(&stream->writeBuffer); } else { dyad_vectorSplice(&stream->writeBuffer, 0, size); } /* Update status */ stream->bytesSent += size; stream->lastActivity = dyad_getTime(); } if (stream->writeBuffer.length == 0) { dyad_Event e; /* If this is a 'closing' stream we can properly close it now */ if (stream->state == DYAD_STATE_CLOSING) { dyad_close(stream); return 0; } /* Set ready flag and emit 'ready for data' event */ stream->flags |= DYAD_FLAG_READY; e = dyad_createEvent(DYAD_EVENT_READY); e.msg = "stream is ready for more data"; dyad_emitEvent(stream, &e); } /* Return 1 to indicate that more data can immediately be written to the * stream's socket */ return 1; }
void dyad_shutdown(void) { /* Close and destroy all the streams */ while (dyad_streams) { dyad_close(dyad_streams); dyad_destroyStream(dyad_streams); } /* Clear up everything */ dyad_selectDeinit(&dyad_selectSet); #ifdef _WIN32 WSACleanup(); #endif }
static void dyad_streamError(dyad_Stream *stream, const char *msg, int err) { char buf[256]; dyad_Event e = dyad_createEvent(DYAD_EVENT_ERROR); if (err) { sprintf(buf, "%.160s (%.80s)", msg, strerror(err)); e.msg = buf; } else { e.msg = msg; } dyad_emitEvent(stream, &e); dyad_close(stream); }
static void dyad_updateStreamTimeouts(void) { double currentTime = dyad_getTime(); dyad_Stream *stream; dyad_Event e = dyad_createEvent(DYAD_EVENT_TIMEOUT); e.msg = "stream timed out"; stream = dyad_streams; while (stream) { if (stream->timeout) { if (currentTime - stream->lastActivity > stream->timeout) { dyad_emitEvent(stream, &e); dyad_close(stream); } } stream = stream->next; } }
static void dyad_handleReceivedData(dyad_Stream *stream) { for (;;) { /* Receive data */ dyad_Event e; char data[8192]; int size = recv(stream->sockfd, data, sizeof(data) - 1, 0); if (size <= 0) { if (size == 0 || errno != EWOULDBLOCK) { /* Handle disconnect */ dyad_close(stream); return; } else { /* No more data */ return; } } data[size] = 0; /* Update status */ stream->bytesReceived += size; stream->lastActivity = dyad_getTime(); /* Emit data event */ e = dyad_createEvent(DYAD_EVENT_DATA); e.msg = "received data"; e.data = data; e.size = size; dyad_emitEvent(stream, &e); /* Check stream state in case it was closed during one of the data event * handlers. */ if (stream->state != DYAD_STATE_CONNECTED) { return; } /* Handle line event */ if (dyad_hasListenerForEvent(stream, DYAD_EVENT_LINE)) { int i, start; char *buf; for (i = 0; i < size; i++) { dyad_vectorPush(&stream->lineBuffer, data[i]); } start = 0; buf = stream->lineBuffer.data; for (i = 0; i < stream->lineBuffer.length; i++) { if (buf[i] == '\n') { dyad_Event e; buf[i] = '\0'; e = dyad_createEvent(DYAD_EVENT_LINE); e.msg = "received line"; e.data = &buf[start]; e.size = i - start; /* Check and strip carriage return */ if (e.size > 0 && e.data[e.size - 1] == '\r') { e.data[--e.size] = '\0'; } dyad_emitEvent(stream, &e); start = i + 1; /* Check stream state in case it was closed during one of the line * event handlers. */ if (stream->state != DYAD_STATE_CONNECTED) { return; } } } if (start == stream->lineBuffer.length) { dyad_vectorClear(&stream->lineBuffer); } else { dyad_vectorSplice(&stream->lineBuffer, 0, start); } } } }
void close() { dyad_close(m_wrap); }