2016-01-29 01:26:31 +08:00
|
|
|
#ifndef _WINSOCK_DEPRECATED_NO_WARNINGS
|
2016-01-19 03:34:24 +08:00
|
|
|
#define _WINSOCK_DEPRECATED_NO_WARNINGS
|
2016-01-29 01:26:31 +08:00
|
|
|
#endif
|
2014-04-02 21:02:54 +08:00
|
|
|
#include "private-libwebsockets.h"
|
|
|
|
|
|
|
|
unsigned long long
|
2014-03-31 11:01:32 +08:00
|
|
|
time_in_microseconds()
|
|
|
|
{
|
2017-01-17 06:51:11 +08:00
|
|
|
#ifndef DELTA_EPOCH_IN_MICROSECS
|
2014-03-31 11:01:32 +08:00
|
|
|
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
|
2017-01-17 06:51:11 +08:00
|
|
|
#endif
|
2014-03-31 11:01:32 +08:00
|
|
|
FILETIME filetime;
|
|
|
|
ULARGE_INTEGER datetime;
|
|
|
|
|
|
|
|
#ifdef _WIN32_WCE
|
|
|
|
GetCurrentFT(&filetime);
|
|
|
|
#else
|
|
|
|
GetSystemTimeAsFileTime(&filetime);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
|
|
* As per Windows documentation for FILETIME, copy the resulting FILETIME structure to a
|
|
|
|
* ULARGE_INTEGER structure using memcpy (using memcpy instead of direct assignment can
|
|
|
|
* prevent alignment faults on 64-bit Windows).
|
|
|
|
*/
|
|
|
|
memcpy(&datetime, &filetime, sizeof(datetime));
|
|
|
|
|
|
|
|
/* Windows file times are in 100s of nanoseconds. */
|
|
|
|
return (datetime.QuadPart - DELTA_EPOCH_IN_MICROSECS) / 10;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef _WIN32_WCE
|
2014-04-02 21:02:54 +08:00
|
|
|
time_t time(time_t *t)
|
2014-03-31 11:01:32 +08:00
|
|
|
{
|
|
|
|
time_t ret = time_in_microseconds() / 1000000;
|
2016-05-05 12:57:11 +02:00
|
|
|
|
|
|
|
if(t != NULL)
|
|
|
|
*t = ret;
|
|
|
|
|
2014-03-31 11:01:32 +08:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-01-30 10:13:01 +08:00
|
|
|
/* file descriptor hash management */
|
|
|
|
|
2015-12-04 11:08:32 +08:00
|
|
|
struct lws *
|
2015-12-14 11:34:00 +08:00
|
|
|
wsi_from_fd(const struct lws_context *context, lws_sockfd_type fd)
|
2015-01-30 10:13:01 +08:00
|
|
|
{
|
|
|
|
int h = LWS_FD_HASH(fd);
|
|
|
|
int n = 0;
|
|
|
|
|
|
|
|
for (n = 0; n < context->fd_hashtable[h].length; n++)
|
2017-02-27 12:55:56 +08:00
|
|
|
if (context->fd_hashtable[h].wsi[n]->desc.sockfd == fd)
|
2015-01-30 10:13:01 +08:00
|
|
|
return context->fd_hashtable[h].wsi[n];
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2015-12-04 11:08:32 +08:00
|
|
|
insert_wsi(struct lws_context *context, struct lws *wsi)
|
2015-01-30 10:13:01 +08:00
|
|
|
{
|
2017-02-27 12:55:56 +08:00
|
|
|
int h = LWS_FD_HASH(wsi->desc.sockfd);
|
2015-01-30 10:13:01 +08:00
|
|
|
|
|
|
|
if (context->fd_hashtable[h].length == (getdtablesize() - 1)) {
|
|
|
|
lwsl_err("hash table overflow\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
context->fd_hashtable[h].wsi[context->fd_hashtable[h].length++] = wsi;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2015-12-06 08:00:03 +08:00
|
|
|
delete_from_fd(struct lws_context *context, lws_sockfd_type fd)
|
2015-01-30 10:13:01 +08:00
|
|
|
{
|
|
|
|
int h = LWS_FD_HASH(fd);
|
|
|
|
int n = 0;
|
|
|
|
|
|
|
|
for (n = 0; n < context->fd_hashtable[h].length; n++)
|
2017-02-27 12:55:56 +08:00
|
|
|
if (context->fd_hashtable[h].wsi[n]->desc.sockfd == fd) {
|
2015-01-30 10:13:01 +08:00
|
|
|
while (n < context->fd_hashtable[h].length) {
|
|
|
|
context->fd_hashtable[h].wsi[n] =
|
2016-07-11 21:17:21 +08:00
|
|
|
context->fd_hashtable[h].wsi[n + 1];
|
2015-01-30 10:13:01 +08:00
|
|
|
n++;
|
|
|
|
}
|
|
|
|
context->fd_hashtable[h].length--;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
lwsl_err("Failed to find fd %d requested for "
|
|
|
|
"delete in hashtable\n", fd);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2015-12-04 11:08:32 +08:00
|
|
|
LWS_VISIBLE int lws_get_random(struct lws_context *context,
|
2016-07-11 21:17:21 +08:00
|
|
|
void *buf, int len)
|
2014-03-31 11:01:32 +08:00
|
|
|
{
|
|
|
|
int n;
|
|
|
|
char *p = (char *)buf;
|
|
|
|
|
|
|
|
for (n = 0; n < len; n++)
|
|
|
|
p[n] = (unsigned char)rand();
|
|
|
|
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
2015-12-04 11:08:32 +08:00
|
|
|
LWS_VISIBLE int lws_send_pipe_choked(struct lws *wsi)
|
2014-03-31 11:01:32 +08:00
|
|
|
{
|
2017-04-18 15:18:14 +08:00
|
|
|
/* treat the fact we got a truncated send pending as if we're choked */
|
|
|
|
if (wsi->trunc_len)
|
|
|
|
return 1;
|
|
|
|
|
2015-12-26 08:56:58 +08:00
|
|
|
return (int)wsi->sock_send_blocking;
|
2014-03-31 11:01:32 +08:00
|
|
|
}
|
|
|
|
|
2015-12-04 11:08:32 +08:00
|
|
|
LWS_VISIBLE int lws_poll_listen_fd(struct lws_pollfd *fd)
|
2014-03-31 11:01:32 +08:00
|
|
|
{
|
|
|
|
fd_set readfds;
|
|
|
|
struct timeval tv = { 0, 0 };
|
|
|
|
|
2016-02-18 21:01:27 +08:00
|
|
|
assert((fd->events & LWS_POLLIN) == LWS_POLLIN);
|
2014-03-31 11:01:32 +08:00
|
|
|
|
|
|
|
FD_ZERO(&readfds);
|
|
|
|
FD_SET(fd->fd, &readfds);
|
|
|
|
|
|
|
|
return select(fd->fd + 1, &readfds, NULL, NULL, &tv);
|
|
|
|
}
|
|
|
|
|
|
|
|
LWS_VISIBLE void
|
2015-12-04 11:08:32 +08:00
|
|
|
lws_cancel_service(struct lws_context *context)
|
2014-03-31 11:01:32 +08:00
|
|
|
{
|
2016-01-19 03:34:24 +08:00
|
|
|
struct lws_context_per_thread *pt = &context->pt[0];
|
|
|
|
int n = context->count_threads;
|
|
|
|
|
|
|
|
while (n--) {
|
|
|
|
WSASetEvent(pt->events[0]);
|
|
|
|
pt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
LWS_VISIBLE void
|
|
|
|
lws_cancel_service_pt(struct lws *wsi)
|
|
|
|
{
|
|
|
|
struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi];
|
|
|
|
WSASetEvent(pt->events[0]);
|
2014-03-31 11:01:32 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
LWS_VISIBLE void lwsl_emit_syslog(int level, const char *line)
|
|
|
|
{
|
|
|
|
lwsl_emit_stderr(level, line);
|
|
|
|
}
|
2014-04-02 14:25:10 +08:00
|
|
|
|
2016-10-07 03:19:17 +08:00
|
|
|
LWS_VISIBLE LWS_EXTERN int
|
2016-10-20 09:09:56 +08:00
|
|
|
_lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi)
|
2014-04-02 14:25:10 +08:00
|
|
|
{
|
2016-12-24 07:57:34 +08:00
|
|
|
struct lws_context_per_thread *pt;
|
2014-04-02 14:25:10 +08:00
|
|
|
WSANETWORKEVENTS networkevents;
|
2015-12-04 11:08:32 +08:00
|
|
|
struct lws_pollfd *pfd;
|
|
|
|
struct lws *wsi;
|
ah owns rxbuf
This is intended to solve a longstanding problem with the
relationship between http/1.1 keep-alive and the service
loop.
Ah now contain an rx buffer which is used during header
processing, and the ah may not be detached from the wsi
until the rx buffer is exhausted.
Having the rx buffer in the ah means we can delay using the
rx until a later service loop.
Ah which have pending rx force POLLIN service on the wsi
they are attached to automatically, so we can interleave
general service / connections with draining each ah rx
buffer.
The possible http/1.1 situations and their dispositions are:
1) exactly one set of http headers come. After processing,
the ah is detached since no pending rx left. If more
headers come later, a fresh ah is aqcuired when available
and the rx flow control blocks the read until then.
2) more that one whole set of headers come and we remain in
http mode (no upgrade). The ah is left attached and
returns to the service loop after the first set of headers.
We will get forced service due to the ah having pending
content (respecting flowcontrol) and process the pending
rx in the ah. If we use it all up, we will detach the
ah.
3) one set of http headers come with ws traffic appended.
We service the headers, do the upgrade, and keep the ah
until the remaining ws content is used. When we
exhausted the ws traffix in the ah rx buffer, we
detach the ah.
Since there can be any amount of http/1.1 pipelining on a
connection, and each may be expensive to service, it's now
enforced there is a return to the service loop after each
header set is serviced on a connection.
When I added the forced service for ah with pending buffering,
I added support for it to the windows plat code. However this
is untested.
Signed-off-by: Andy Green <andy.green@linaro.org>
2016-02-15 12:37:04 +08:00
|
|
|
unsigned int i;
|
|
|
|
DWORD ev;
|
|
|
|
int n, m;
|
2014-04-02 14:25:10 +08:00
|
|
|
|
|
|
|
/* stay dead once we are dead */
|
|
|
|
if (context == NULL)
|
|
|
|
return 1;
|
|
|
|
|
2016-12-24 07:57:34 +08:00
|
|
|
pt = &context->pt[tsi];
|
|
|
|
|
2015-12-24 13:00:54 +08:00
|
|
|
if (!context->service_tid_detected) {
|
|
|
|
struct lws _lws;
|
|
|
|
|
|
|
|
memset(&_lws, 0, sizeof(_lws));
|
|
|
|
_lws.context = context;
|
|
|
|
|
2016-03-28 10:10:43 +08:00
|
|
|
context->service_tid_detected = context->vhost_list->
|
|
|
|
protocols[0].callback(&_lws, LWS_CALLBACK_GET_THREAD_ID,
|
2016-07-11 21:17:21 +08:00
|
|
|
NULL, NULL, 0);
|
2015-12-24 13:00:54 +08:00
|
|
|
}
|
|
|
|
context->service_tid = context->service_tid_detected;
|
2014-04-02 14:25:10 +08:00
|
|
|
|
2016-04-06 09:23:16 +08:00
|
|
|
if (timeout_ms < 0)
|
2016-07-11 21:17:21 +08:00
|
|
|
{
|
|
|
|
if (lws_service_flag_pending(context, tsi)) {
|
|
|
|
/* any socket with events to service? */
|
|
|
|
for (n = 0; n < (int)pt->fds_count; n++) {
|
|
|
|
if (!pt->fds[n].revents)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
m = lws_service_fd_tsi(context, &pt->fds[n], tsi);
|
|
|
|
if (m < 0)
|
|
|
|
return -1;
|
|
|
|
/* if something closed, retry this slot */
|
|
|
|
if (m)
|
|
|
|
n--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2016-04-06 09:23:16 +08:00
|
|
|
|
2016-01-19 03:34:24 +08:00
|
|
|
for (i = 0; i < pt->fds_count; ++i) {
|
|
|
|
pfd = &pt->fds[i];
|
2016-03-28 10:10:43 +08:00
|
|
|
|
|
|
|
if (!(pfd->events & LWS_POLLOUT))
|
2014-04-02 14:25:10 +08:00
|
|
|
continue;
|
|
|
|
|
2016-03-28 10:10:43 +08:00
|
|
|
wsi = wsi_from_fd(context, pfd->fd);
|
|
|
|
if (wsi->listener)
|
|
|
|
continue;
|
|
|
|
if (!wsi || wsi->sock_send_blocking)
|
|
|
|
continue;
|
|
|
|
pfd->revents = LWS_POLLOUT;
|
|
|
|
n = lws_service_fd(context, pfd);
|
|
|
|
if (n < 0)
|
|
|
|
return -1;
|
|
|
|
/* if something closed, retry this slot */
|
|
|
|
if (n)
|
|
|
|
i--;
|
2014-04-02 14:25:10 +08:00
|
|
|
}
|
|
|
|
|
2016-10-10 20:34:34 +08:00
|
|
|
/*
|
|
|
|
* is there anybody with pending stuff that needs service forcing?
|
|
|
|
*/
|
|
|
|
if (!lws_service_adjust_timeout(context, 1, tsi)) {
|
|
|
|
/* -1 timeout means just do forced service */
|
2016-10-20 09:09:56 +08:00
|
|
|
_lws_plat_service_tsi(context, -1, pt->tid);
|
2016-10-10 20:34:34 +08:00
|
|
|
/* still somebody left who wants forced service? */
|
|
|
|
if (!lws_service_adjust_timeout(context, 1, pt->tid))
|
|
|
|
/* yes... come back again quickly */
|
|
|
|
timeout_ms = 0;
|
|
|
|
}
|
ah owns rxbuf
This is intended to solve a longstanding problem with the
relationship between http/1.1 keep-alive and the service
loop.
Ah now contain an rx buffer which is used during header
processing, and the ah may not be detached from the wsi
until the rx buffer is exhausted.
Having the rx buffer in the ah means we can delay using the
rx until a later service loop.
Ah which have pending rx force POLLIN service on the wsi
they are attached to automatically, so we can interleave
general service / connections with draining each ah rx
buffer.
The possible http/1.1 situations and their dispositions are:
1) exactly one set of http headers come. After processing,
the ah is detached since no pending rx left. If more
headers come later, a fresh ah is aqcuired when available
and the rx flow control blocks the read until then.
2) more that one whole set of headers come and we remain in
http mode (no upgrade). The ah is left attached and
returns to the service loop after the first set of headers.
We will get forced service due to the ah having pending
content (respecting flowcontrol) and process the pending
rx in the ah. If we use it all up, we will detach the
ah.
3) one set of http headers come with ws traffic appended.
We service the headers, do the upgrade, and keep the ah
until the remaining ws content is used. When we
exhausted the ws traffix in the ah rx buffer, we
detach the ah.
Since there can be any amount of http/1.1 pipelining on a
connection, and each may be expensive to service, it's now
enforced there is a return to the service loop after each
header set is serviced on a connection.
When I added the forced service for ah with pending buffering,
I added support for it to the windows plat code. However this
is untested.
Signed-off-by: Andy Green <andy.green@linaro.org>
2016-02-15 12:37:04 +08:00
|
|
|
|
2016-07-11 21:17:21 +08:00
|
|
|
ev = WSAWaitForMultipleEvents( 1, pt->events , FALSE, timeout_ms, FALSE);
|
2014-04-02 14:25:10 +08:00
|
|
|
if (ev == WSA_WAIT_EVENT_0) {
|
2017-01-18 07:20:09 +08:00
|
|
|
unsigned int eIdx;
|
2014-04-02 14:25:10 +08:00
|
|
|
|
2016-07-11 21:17:21 +08:00
|
|
|
WSAResetEvent(pt->events[0]);
|
2014-04-02 14:25:10 +08:00
|
|
|
|
2017-01-18 07:20:09 +08:00
|
|
|
for (eIdx = 0; eIdx < pt->fds_count; ++eIdx) {
|
2016-07-11 21:17:21 +08:00
|
|
|
if (WSAEnumNetworkEvents(pt->fds[eIdx].fd, 0, &networkevents) == SOCKET_ERROR) {
|
|
|
|
lwsl_err("WSAEnumNetworkEvents() failed with error %d\n", LWS_ERRNO);
|
|
|
|
return -1;
|
|
|
|
}
|
ah owns rxbuf
This is intended to solve a longstanding problem with the
relationship between http/1.1 keep-alive and the service
loop.
Ah now contain an rx buffer which is used during header
processing, and the ah may not be detached from the wsi
until the rx buffer is exhausted.
Having the rx buffer in the ah means we can delay using the
rx until a later service loop.
Ah which have pending rx force POLLIN service on the wsi
they are attached to automatically, so we can interleave
general service / connections with draining each ah rx
buffer.
The possible http/1.1 situations and their dispositions are:
1) exactly one set of http headers come. After processing,
the ah is detached since no pending rx left. If more
headers come later, a fresh ah is aqcuired when available
and the rx flow control blocks the read until then.
2) more that one whole set of headers come and we remain in
http mode (no upgrade). The ah is left attached and
returns to the service loop after the first set of headers.
We will get forced service due to the ah having pending
content (respecting flowcontrol) and process the pending
rx in the ah. If we use it all up, we will detach the
ah.
3) one set of http headers come with ws traffic appended.
We service the headers, do the upgrade, and keep the ah
until the remaining ws content is used. When we
exhausted the ws traffix in the ah rx buffer, we
detach the ah.
Since there can be any amount of http/1.1 pipelining on a
connection, and each may be expensive to service, it's now
enforced there is a return to the service loop after each
header set is serviced on a connection.
When I added the forced service for ah with pending buffering,
I added support for it to the windows plat code. However this
is untested.
Signed-off-by: Andy Green <andy.green@linaro.org>
2016-02-15 12:37:04 +08:00
|
|
|
|
2016-07-11 21:17:21 +08:00
|
|
|
pfd = &pt->fds[eIdx];
|
|
|
|
pfd->revents = (short)networkevents.lNetworkEvents;
|
|
|
|
|
|
|
|
if ((networkevents.lNetworkEvents & FD_CONNECT) &&
|
|
|
|
networkevents.iErrorCode[FD_CONNECT_BIT] &&
|
|
|
|
networkevents.iErrorCode[FD_CONNECT_BIT] != LWS_EALREADY &&
|
|
|
|
networkevents.iErrorCode[FD_CONNECT_BIT] != LWS_EINPROGRESS &&
|
|
|
|
networkevents.iErrorCode[FD_CONNECT_BIT] != LWS_EWOULDBLOCK &&
|
|
|
|
networkevents.iErrorCode[FD_CONNECT_BIT] != WSAEINVAL) {
|
|
|
|
lwsl_debug("Unable to connect errno=%d\n",
|
|
|
|
networkevents.iErrorCode[FD_CONNECT_BIT]);
|
|
|
|
pfd->revents = LWS_POLLHUP;
|
|
|
|
} else
|
|
|
|
pfd->revents = (short)networkevents.lNetworkEvents;
|
|
|
|
|
|
|
|
if (pfd->revents & LWS_POLLOUT) {
|
|
|
|
wsi = wsi_from_fd(context, pfd->fd);
|
|
|
|
if (wsi)
|
|
|
|
wsi->sock_send_blocking = 0;
|
|
|
|
}
|
2016-07-11 21:17:48 +08:00
|
|
|
/* if something closed, retry this slot */
|
|
|
|
if (pfd->revents & LWS_POLLHUP)
|
|
|
|
--eIdx;
|
ah owns rxbuf
This is intended to solve a longstanding problem with the
relationship between http/1.1 keep-alive and the service
loop.
Ah now contain an rx buffer which is used during header
processing, and the ah may not be detached from the wsi
until the rx buffer is exhausted.
Having the rx buffer in the ah means we can delay using the
rx until a later service loop.
Ah which have pending rx force POLLIN service on the wsi
they are attached to automatically, so we can interleave
general service / connections with draining each ah rx
buffer.
The possible http/1.1 situations and their dispositions are:
1) exactly one set of http headers come. After processing,
the ah is detached since no pending rx left. If more
headers come later, a fresh ah is aqcuired when available
and the rx flow control blocks the read until then.
2) more that one whole set of headers come and we remain in
http mode (no upgrade). The ah is left attached and
returns to the service loop after the first set of headers.
We will get forced service due to the ah having pending
content (respecting flowcontrol) and process the pending
rx in the ah. If we use it all up, we will detach the
ah.
3) one set of http headers come with ws traffic appended.
We service the headers, do the upgrade, and keep the ah
until the remaining ws content is used. When we
exhausted the ws traffix in the ah rx buffer, we
detach the ah.
Since there can be any amount of http/1.1 pipelining on a
connection, and each may be expensive to service, it's now
enforced there is a return to the service loop after each
header set is serviced on a connection.
When I added the forced service for ah with pending buffering,
I added support for it to the windows plat code. However this
is untested.
Signed-off-by: Andy Green <andy.green@linaro.org>
2016-02-15 12:37:04 +08:00
|
|
|
|
2016-07-11 21:17:48 +08:00
|
|
|
if( pfd->revents != 0 ) {
|
2016-07-11 21:17:21 +08:00
|
|
|
lws_service_fd_tsi(context, pfd, tsi);
|
2016-07-11 21:17:48 +08:00
|
|
|
|
2016-07-11 21:17:21 +08:00
|
|
|
}
|
|
|
|
}
|
ah owns rxbuf
This is intended to solve a longstanding problem with the
relationship between http/1.1 keep-alive and the service
loop.
Ah now contain an rx buffer which is used during header
processing, and the ah may not be detached from the wsi
until the rx buffer is exhausted.
Having the rx buffer in the ah means we can delay using the
rx until a later service loop.
Ah which have pending rx force POLLIN service on the wsi
they are attached to automatically, so we can interleave
general service / connections with draining each ah rx
buffer.
The possible http/1.1 situations and their dispositions are:
1) exactly one set of http headers come. After processing,
the ah is detached since no pending rx left. If more
headers come later, a fresh ah is aqcuired when available
and the rx flow control blocks the read until then.
2) more that one whole set of headers come and we remain in
http mode (no upgrade). The ah is left attached and
returns to the service loop after the first set of headers.
We will get forced service due to the ah having pending
content (respecting flowcontrol) and process the pending
rx in the ah. If we use it all up, we will detach the
ah.
3) one set of http headers come with ws traffic appended.
We service the headers, do the upgrade, and keep the ah
until the remaining ws content is used. When we
exhausted the ws traffix in the ah rx buffer, we
detach the ah.
Since there can be any amount of http/1.1 pipelining on a
connection, and each may be expensive to service, it's now
enforced there is a return to the service loop after each
header set is serviced on a connection.
When I added the forced service for ah with pending buffering,
I added support for it to the windows plat code. However this
is untested.
Signed-off-by: Andy Green <andy.green@linaro.org>
2016-02-15 12:37:04 +08:00
|
|
|
}
|
|
|
|
|
2016-07-11 21:17:21 +08:00
|
|
|
context->service_tid = 0;
|
ah owns rxbuf
This is intended to solve a longstanding problem with the
relationship between http/1.1 keep-alive and the service
loop.
Ah now contain an rx buffer which is used during header
processing, and the ah may not be detached from the wsi
until the rx buffer is exhausted.
Having the rx buffer in the ah means we can delay using the
rx until a later service loop.
Ah which have pending rx force POLLIN service on the wsi
they are attached to automatically, so we can interleave
general service / connections with draining each ah rx
buffer.
The possible http/1.1 situations and their dispositions are:
1) exactly one set of http headers come. After processing,
the ah is detached since no pending rx left. If more
headers come later, a fresh ah is aqcuired when available
and the rx flow control blocks the read until then.
2) more that one whole set of headers come and we remain in
http mode (no upgrade). The ah is left attached and
returns to the service loop after the first set of headers.
We will get forced service due to the ah having pending
content (respecting flowcontrol) and process the pending
rx in the ah. If we use it all up, we will detach the
ah.
3) one set of http headers come with ws traffic appended.
We service the headers, do the upgrade, and keep the ah
until the remaining ws content is used. When we
exhausted the ws traffix in the ah rx buffer, we
detach the ah.
Since there can be any amount of http/1.1 pipelining on a
connection, and each may be expensive to service, it's now
enforced there is a return to the service loop after each
header set is serviced on a connection.
When I added the forced service for ah with pending buffering,
I added support for it to the windows plat code. However this
is untested.
Signed-off-by: Andy Green <andy.green@linaro.org>
2016-02-15 12:37:04 +08:00
|
|
|
|
2016-07-11 21:17:21 +08:00
|
|
|
if (ev == WSA_WAIT_TIMEOUT) {
|
|
|
|
lws_service_fd(context, NULL);
|
|
|
|
}
|
|
|
|
return 0;;
|
2014-04-02 14:25:10 +08:00
|
|
|
}
|
|
|
|
|
2016-01-19 03:34:24 +08:00
|
|
|
LWS_VISIBLE int
|
|
|
|
lws_plat_service(struct lws_context *context, int timeout_ms)
|
|
|
|
{
|
2016-10-20 09:09:56 +08:00
|
|
|
return _lws_plat_service_tsi(context, timeout_ms, 0);
|
2016-01-19 03:34:24 +08:00
|
|
|
}
|
|
|
|
|
2014-04-02 21:02:54 +08:00
|
|
|
LWS_VISIBLE int
|
2016-03-28 10:10:43 +08:00
|
|
|
lws_plat_set_socket_options(struct lws_vhost *vhost, lws_sockfd_type fd)
|
2014-04-02 14:25:10 +08:00
|
|
|
{
|
|
|
|
int optval = 1;
|
2014-04-15 18:41:38 +02:00
|
|
|
int optlen = sizeof(optval);
|
2014-04-02 14:25:10 +08:00
|
|
|
u_long optl = 1;
|
|
|
|
DWORD dwBytesRet;
|
|
|
|
struct tcp_keepalive alive;
|
2016-02-29 18:48:55 +08:00
|
|
|
int protonbr;
|
|
|
|
#ifndef _WIN32_WCE
|
2014-04-03 22:38:49 +08:00
|
|
|
struct protoent *tcp_proto;
|
2016-02-29 18:48:55 +08:00
|
|
|
#endif
|
2015-12-14 08:52:03 +08:00
|
|
|
|
2016-03-28 10:10:43 +08:00
|
|
|
if (vhost->ka_time) {
|
2014-04-02 14:25:10 +08:00
|
|
|
/* enable keepalive on this socket */
|
|
|
|
optval = 1;
|
|
|
|
if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE,
|
2016-07-11 21:17:21 +08:00
|
|
|
(const char *)&optval, optlen) < 0)
|
2014-04-02 14:25:10 +08:00
|
|
|
return 1;
|
|
|
|
|
|
|
|
alive.onoff = TRUE;
|
2016-03-28 10:10:43 +08:00
|
|
|
alive.keepalivetime = vhost->ka_time;
|
|
|
|
alive.keepaliveinterval = vhost->ka_interval;
|
2014-04-02 14:25:10 +08:00
|
|
|
|
2015-12-14 08:52:03 +08:00
|
|
|
if (WSAIoctl(fd, SIO_KEEPALIVE_VALS, &alive, sizeof(alive),
|
2016-07-11 21:17:21 +08:00
|
|
|
NULL, 0, &dwBytesRet, NULL, NULL))
|
2014-04-02 14:25:10 +08:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Disable Nagle */
|
|
|
|
optval = 1;
|
2016-02-29 18:48:55 +08:00
|
|
|
#ifndef _WIN32_WCE
|
2014-04-02 14:25:10 +08:00
|
|
|
tcp_proto = getprotobyname("TCP");
|
2015-04-16 04:24:38 +08:00
|
|
|
if (!tcp_proto) {
|
|
|
|
lwsl_err("getprotobyname() failed with error %d\n", LWS_ERRNO);
|
|
|
|
return 1;
|
|
|
|
}
|
2016-02-29 18:48:55 +08:00
|
|
|
protonbr = tcp_proto->p_proto;
|
|
|
|
#else
|
|
|
|
protonbr = 6;
|
|
|
|
#endif
|
2015-04-16 04:24:38 +08:00
|
|
|
|
2016-02-29 18:48:55 +08:00
|
|
|
setsockopt(fd, protonbr, TCP_NODELAY, (const char *)&optval, optlen);
|
2014-04-02 14:25:10 +08:00
|
|
|
|
|
|
|
/* We are nonblocking... */
|
|
|
|
ioctlsocket(fd, FIONBIO, &optl);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-04-02 21:02:54 +08:00
|
|
|
LWS_VISIBLE void
|
|
|
|
lws_plat_drop_app_privileges(struct lws_context_creation_info *info)
|
2014-04-02 14:25:10 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2014-04-02 21:02:54 +08:00
|
|
|
LWS_VISIBLE int
|
|
|
|
lws_plat_context_early_init(void)
|
2014-04-02 14:25:10 +08:00
|
|
|
{
|
|
|
|
WORD wVersionRequested;
|
|
|
|
WSADATA wsaData;
|
|
|
|
int err;
|
|
|
|
|
|
|
|
/* Use the MAKEWORD(lowbyte, highbyte) macro from Windef.h */
|
|
|
|
wVersionRequested = MAKEWORD(2, 2);
|
|
|
|
|
|
|
|
err = WSAStartup(wVersionRequested, &wsaData);
|
|
|
|
if (!err)
|
|
|
|
return 0;
|
|
|
|
/*
|
|
|
|
* Tell the user that we could not find a usable
|
|
|
|
* Winsock DLL
|
|
|
|
*/
|
|
|
|
lwsl_err("WSAStartup failed with error: %d\n", err);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2014-04-02 21:02:54 +08:00
|
|
|
LWS_VISIBLE void
|
2015-12-04 11:08:32 +08:00
|
|
|
lws_plat_context_early_destroy(struct lws_context *context)
|
2014-04-02 14:25:10 +08:00
|
|
|
{
|
2016-01-19 03:34:24 +08:00
|
|
|
struct lws_context_per_thread *pt = &context->pt[0];
|
|
|
|
int n = context->count_threads;
|
|
|
|
|
|
|
|
while (n--) {
|
|
|
|
if (pt->events) {
|
|
|
|
WSACloseEvent(pt->events[0]);
|
|
|
|
lws_free(pt->events);
|
|
|
|
}
|
|
|
|
pt++;
|
2014-04-02 14:25:10 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-02 21:02:54 +08:00
|
|
|
LWS_VISIBLE void
|
2015-12-04 11:08:32 +08:00
|
|
|
lws_plat_context_late_destroy(struct lws_context *context)
|
2014-04-02 14:25:10 +08:00
|
|
|
{
|
2015-06-25 17:51:07 +02:00
|
|
|
int n;
|
|
|
|
|
|
|
|
for (n = 0; n < FD_HASHTABLE_MODULUS; n++) {
|
|
|
|
if (context->fd_hashtable[n].wsi)
|
|
|
|
lws_free(context->fd_hashtable[n].wsi);
|
|
|
|
}
|
|
|
|
|
2014-04-02 14:25:10 +08:00
|
|
|
WSACleanup();
|
|
|
|
}
|
|
|
|
|
2016-01-16 12:09:38 +08:00
|
|
|
LWS_VISIBLE LWS_EXTERN int
|
|
|
|
lws_interface_to_sa(int ipv6,
|
2014-04-02 14:25:10 +08:00
|
|
|
const char *ifname, struct sockaddr_in *addr, size_t addrlen)
|
|
|
|
{
|
2014-11-06 23:06:01 +08:00
|
|
|
long long address = inet_addr(ifname);
|
|
|
|
|
|
|
|
if (address == INADDR_NONE) {
|
|
|
|
struct hostent *entry = gethostbyname(ifname);
|
|
|
|
if (entry)
|
|
|
|
address = ((struct in_addr *)entry->h_addr_list[0])->s_addr;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (address == INADDR_NONE)
|
|
|
|
return -1;
|
|
|
|
|
2015-12-06 08:00:03 +08:00
|
|
|
addr->sin_addr.s_addr = (unsigned long)address;
|
2014-11-06 23:06:01 +08:00
|
|
|
|
|
|
|
return 0;
|
2014-04-02 14:25:10 +08:00
|
|
|
}
|
|
|
|
|
2014-04-02 21:02:54 +08:00
|
|
|
LWS_VISIBLE void
|
2016-01-19 03:34:24 +08:00
|
|
|
lws_plat_insert_socket_into_fds(struct lws_context *context, struct lws *wsi)
|
2014-04-02 14:25:10 +08:00
|
|
|
{
|
2016-01-19 03:34:24 +08:00
|
|
|
struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
|
|
|
|
|
|
|
|
pt->fds[pt->fds_count++].revents = 0;
|
2016-07-11 21:17:21 +08:00
|
|
|
pt->events[pt->fds_count] = pt->events[0];
|
2017-02-27 12:55:56 +08:00
|
|
|
WSAEventSelect(wsi->desc.sockfd, pt->events[0],
|
2016-07-11 21:17:21 +08:00
|
|
|
LWS_POLLIN | LWS_POLLHUP | FD_CONNECT);
|
2014-04-02 14:25:10 +08:00
|
|
|
}
|
|
|
|
|
2014-04-02 21:02:54 +08:00
|
|
|
LWS_VISIBLE void
|
2015-12-04 11:08:32 +08:00
|
|
|
lws_plat_delete_socket_from_fds(struct lws_context *context,
|
|
|
|
struct lws *wsi, int m)
|
2014-04-02 14:25:10 +08:00
|
|
|
{
|
2016-01-19 03:34:24 +08:00
|
|
|
struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
|
|
|
|
|
2016-01-26 20:56:56 +08:00
|
|
|
pt->events[m + 1] = pt->events[pt->fds_count--];
|
2014-04-02 14:25:10 +08:00
|
|
|
}
|
|
|
|
|
2014-04-02 21:02:54 +08:00
|
|
|
LWS_VISIBLE void
|
2015-12-04 11:08:32 +08:00
|
|
|
lws_plat_service_periodic(struct lws_context *context)
|
2014-04-02 14:25:10 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2016-06-28 19:01:20 +08:00
|
|
|
LWS_VISIBLE int
|
|
|
|
lws_plat_check_connection_error(struct lws *wsi)
|
|
|
|
{
|
|
|
|
int optVal;
|
|
|
|
int optLen = sizeof(int);
|
|
|
|
|
2017-02-27 12:55:56 +08:00
|
|
|
if (getsockopt(wsi->desc.sockfd, SOL_SOCKET, SO_ERROR,
|
2016-07-11 21:17:21 +08:00
|
|
|
(char*)&optVal, &optLen) != SOCKET_ERROR && optVal &&
|
|
|
|
optVal != LWS_EALREADY && optVal != LWS_EINPROGRESS &&
|
|
|
|
optVal != LWS_EWOULDBLOCK && optVal != WSAEINVAL) {
|
|
|
|
lwsl_debug("Connect failed SO_ERROR=%d\n", optVal);
|
|
|
|
return 1;
|
2016-06-28 19:01:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-04-02 21:02:54 +08:00
|
|
|
LWS_VISIBLE int
|
2015-12-04 11:08:32 +08:00
|
|
|
lws_plat_change_pollfd(struct lws_context *context,
|
2016-07-11 21:17:21 +08:00
|
|
|
struct lws *wsi, struct lws_pollfd *pfd)
|
2014-04-02 14:25:10 +08:00
|
|
|
{
|
2016-01-19 03:34:24 +08:00
|
|
|
struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
|
2016-06-28 19:01:20 +08:00
|
|
|
long networkevents = LWS_POLLHUP | FD_CONNECT;
|
2015-12-14 08:52:03 +08:00
|
|
|
|
2014-04-02 14:25:10 +08:00
|
|
|
if ((pfd->events & LWS_POLLIN))
|
|
|
|
networkevents |= LWS_POLLIN;
|
2015-12-14 08:52:03 +08:00
|
|
|
|
2015-11-18 09:51:07 +08:00
|
|
|
if ((pfd->events & LWS_POLLOUT))
|
|
|
|
networkevents |= LWS_POLLOUT;
|
2014-04-02 14:25:10 +08:00
|
|
|
|
2017-02-27 12:55:56 +08:00
|
|
|
if (WSAEventSelect(wsi->desc.sockfd,
|
2016-07-11 21:17:21 +08:00
|
|
|
pt->events[0],
|
|
|
|
networkevents) != SOCKET_ERROR)
|
2014-04-02 14:25:10 +08:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
lwsl_err("WSAEventSelect() failed with error %d\n", LWS_ERRNO);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2014-04-02 23:03:23 +08:00
|
|
|
LWS_VISIBLE const char *
|
|
|
|
lws_plat_inet_ntop(int af, const void *src, char *dst, int cnt)
|
2015-12-14 08:52:03 +08:00
|
|
|
{
|
2014-04-15 18:45:48 +02:00
|
|
|
WCHAR *buffer;
|
|
|
|
DWORD bufferlen = cnt;
|
|
|
|
BOOL ok = FALSE;
|
|
|
|
|
2016-09-05 15:03:37 +08:00
|
|
|
buffer = lws_malloc(bufferlen * 2);
|
2014-04-15 18:45:48 +02:00
|
|
|
if (!buffer) {
|
|
|
|
lwsl_err("Out of memory\n");
|
|
|
|
return NULL;
|
|
|
|
}
|
2014-04-02 21:31:07 +08:00
|
|
|
|
2014-04-15 18:45:48 +02:00
|
|
|
if (af == AF_INET) {
|
|
|
|
struct sockaddr_in srcaddr;
|
|
|
|
bzero(&srcaddr, sizeof(srcaddr));
|
|
|
|
srcaddr.sin_family = AF_INET;
|
|
|
|
memcpy(&(srcaddr.sin_addr), src, sizeof(srcaddr.sin_addr));
|
2014-04-02 21:31:07 +08:00
|
|
|
|
2014-04-15 18:45:48 +02:00
|
|
|
if (!WSAAddressToStringW((struct sockaddr*)&srcaddr, sizeof(srcaddr), 0, buffer, &bufferlen))
|
|
|
|
ok = TRUE;
|
|
|
|
#ifdef LWS_USE_IPV6
|
|
|
|
} else if (af == AF_INET6) {
|
|
|
|
struct sockaddr_in6 srcaddr;
|
|
|
|
bzero(&srcaddr, sizeof(srcaddr));
|
|
|
|
srcaddr.sin6_family = AF_INET6;
|
|
|
|
memcpy(&(srcaddr.sin6_addr), src, sizeof(srcaddr.sin6_addr));
|
|
|
|
|
|
|
|
if (!WSAAddressToStringW((struct sockaddr*)&srcaddr, sizeof(srcaddr), 0, buffer, &bufferlen))
|
|
|
|
ok = TRUE;
|
|
|
|
#endif
|
|
|
|
} else
|
|
|
|
lwsl_err("Unsupported type\n");
|
|
|
|
|
|
|
|
if (!ok) {
|
|
|
|
int rv = WSAGetLastError();
|
|
|
|
lwsl_err("WSAAddressToString() : %d\n", rv);
|
|
|
|
} else {
|
|
|
|
if (WideCharToMultiByte(CP_ACP, 0, buffer, bufferlen, dst, cnt, 0, NULL) <= 0)
|
|
|
|
ok = FALSE;
|
|
|
|
}
|
2014-04-02 21:31:07 +08:00
|
|
|
|
2014-12-04 23:59:35 +01:00
|
|
|
lws_free(buffer);
|
2014-04-15 18:45:48 +02:00
|
|
|
return ok ? dst : NULL;
|
2014-04-02 23:03:23 +08:00
|
|
|
}
|
lws_plat_fd implement platform default handlers
This is a rewrite of the patch from Soapyman here
https://github.com/warmcat/libwebsockets/pull/363
The main changes compared to Soapyman's original patch are
- There's no new stuff in the info struct user code does any overrides
it may want to do explicitly after lws_context_create returns
- User overrides for file ops can call through (subclass) to the original
platform implementation using lws_get_fops_plat()
- A typedef is provided for plat-specific fd type
- Public helpers are provided to allow user code to be platform-independent
about file access, using the lws platform file operations underneath:
static inline lws_filefd_type
lws_plat_file_open(struct lws_plat_file_ops *fops, const char *filename,
unsigned long *filelen, int flags)
static inline int
lws_plat_file_close(struct lws_plat_file_ops *fops, lws_filefd_type fd)
static inline unsigned long
lws_plat_file_seek_cur(struct lws_plat_file_ops *fops, lws_filefd_type fd,
long offset_from_cur_pos)
static inline int
lws_plat_file_read(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
static inline int
lws_plat_file_write(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
There's example documentation and implementation in the test server.
Signed-off-by: Andy Green <andy.green@linaro.org>
2015-12-10 07:58:58 +08:00
|
|
|
|
2017-03-01 14:28:56 +08:00
|
|
|
LWS_VISIBLE lws_fop_fd_t
|
2017-04-19 20:41:57 +08:00
|
|
|
_lws_plat_file_open(const struct lws_plat_file_ops *fops, const char *filename,
|
2017-03-03 12:38:10 +08:00
|
|
|
const char *vpath, lws_fop_flags_t *flags)
|
lws_plat_fd implement platform default handlers
This is a rewrite of the patch from Soapyman here
https://github.com/warmcat/libwebsockets/pull/363
The main changes compared to Soapyman's original patch are
- There's no new stuff in the info struct user code does any overrides
it may want to do explicitly after lws_context_create returns
- User overrides for file ops can call through (subclass) to the original
platform implementation using lws_get_fops_plat()
- A typedef is provided for plat-specific fd type
- Public helpers are provided to allow user code to be platform-independent
about file access, using the lws platform file operations underneath:
static inline lws_filefd_type
lws_plat_file_open(struct lws_plat_file_ops *fops, const char *filename,
unsigned long *filelen, int flags)
static inline int
lws_plat_file_close(struct lws_plat_file_ops *fops, lws_filefd_type fd)
static inline unsigned long
lws_plat_file_seek_cur(struct lws_plat_file_ops *fops, lws_filefd_type fd,
long offset_from_cur_pos)
static inline int
lws_plat_file_read(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
static inline int
lws_plat_file_write(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
There's example documentation and implementation in the test server.
Signed-off-by: Andy Green <andy.green@linaro.org>
2015-12-10 07:58:58 +08:00
|
|
|
{
|
|
|
|
HANDLE ret;
|
|
|
|
WCHAR buf[MAX_PATH];
|
2017-02-25 12:42:45 +08:00
|
|
|
lws_fop_fd_t fop_fd;
|
lws_plat_fd implement platform default handlers
This is a rewrite of the patch from Soapyman here
https://github.com/warmcat/libwebsockets/pull/363
The main changes compared to Soapyman's original patch are
- There's no new stuff in the info struct user code does any overrides
it may want to do explicitly after lws_context_create returns
- User overrides for file ops can call through (subclass) to the original
platform implementation using lws_get_fops_plat()
- A typedef is provided for plat-specific fd type
- Public helpers are provided to allow user code to be platform-independent
about file access, using the lws platform file operations underneath:
static inline lws_filefd_type
lws_plat_file_open(struct lws_plat_file_ops *fops, const char *filename,
unsigned long *filelen, int flags)
static inline int
lws_plat_file_close(struct lws_plat_file_ops *fops, lws_filefd_type fd)
static inline unsigned long
lws_plat_file_seek_cur(struct lws_plat_file_ops *fops, lws_filefd_type fd,
long offset_from_cur_pos)
static inline int
lws_plat_file_read(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
static inline int
lws_plat_file_write(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
There's example documentation and implementation in the test server.
Signed-off-by: Andy Green <andy.green@linaro.org>
2015-12-10 07:58:58 +08:00
|
|
|
|
|
|
|
MultiByteToWideChar(CP_UTF8, 0, filename, -1, buf, ARRAY_SIZE(buf));
|
2017-02-12 18:15:15 +08:00
|
|
|
if (((*flags) & 7) == _O_RDONLY) {
|
lws_plat_fd implement platform default handlers
This is a rewrite of the patch from Soapyman here
https://github.com/warmcat/libwebsockets/pull/363
The main changes compared to Soapyman's original patch are
- There's no new stuff in the info struct user code does any overrides
it may want to do explicitly after lws_context_create returns
- User overrides for file ops can call through (subclass) to the original
platform implementation using lws_get_fops_plat()
- A typedef is provided for plat-specific fd type
- Public helpers are provided to allow user code to be platform-independent
about file access, using the lws platform file operations underneath:
static inline lws_filefd_type
lws_plat_file_open(struct lws_plat_file_ops *fops, const char *filename,
unsigned long *filelen, int flags)
static inline int
lws_plat_file_close(struct lws_plat_file_ops *fops, lws_filefd_type fd)
static inline unsigned long
lws_plat_file_seek_cur(struct lws_plat_file_ops *fops, lws_filefd_type fd,
long offset_from_cur_pos)
static inline int
lws_plat_file_read(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
static inline int
lws_plat_file_write(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
There's example documentation and implementation in the test server.
Signed-off-by: Andy Green <andy.green@linaro.org>
2015-12-10 07:58:58 +08:00
|
|
|
ret = CreateFileW(buf, GENERIC_READ, FILE_SHARE_READ,
|
|
|
|
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
|
|
} else {
|
|
|
|
lwsl_err("%s: open for write not implemented\n", __func__);
|
2017-02-25 12:42:45 +08:00
|
|
|
goto bail;
|
lws_plat_fd implement platform default handlers
This is a rewrite of the patch from Soapyman here
https://github.com/warmcat/libwebsockets/pull/363
The main changes compared to Soapyman's original patch are
- There's no new stuff in the info struct user code does any overrides
it may want to do explicitly after lws_context_create returns
- User overrides for file ops can call through (subclass) to the original
platform implementation using lws_get_fops_plat()
- A typedef is provided for plat-specific fd type
- Public helpers are provided to allow user code to be platform-independent
about file access, using the lws platform file operations underneath:
static inline lws_filefd_type
lws_plat_file_open(struct lws_plat_file_ops *fops, const char *filename,
unsigned long *filelen, int flags)
static inline int
lws_plat_file_close(struct lws_plat_file_ops *fops, lws_filefd_type fd)
static inline unsigned long
lws_plat_file_seek_cur(struct lws_plat_file_ops *fops, lws_filefd_type fd,
long offset_from_cur_pos)
static inline int
lws_plat_file_read(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
static inline int
lws_plat_file_write(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
There's example documentation and implementation in the test server.
Signed-off-by: Andy Green <andy.green@linaro.org>
2015-12-10 07:58:58 +08:00
|
|
|
}
|
|
|
|
|
2017-02-25 12:42:45 +08:00
|
|
|
if (ret == LWS_INVALID_FILE)
|
|
|
|
goto bail;
|
lws_plat_fd implement platform default handlers
This is a rewrite of the patch from Soapyman here
https://github.com/warmcat/libwebsockets/pull/363
The main changes compared to Soapyman's original patch are
- There's no new stuff in the info struct user code does any overrides
it may want to do explicitly after lws_context_create returns
- User overrides for file ops can call through (subclass) to the original
platform implementation using lws_get_fops_plat()
- A typedef is provided for plat-specific fd type
- Public helpers are provided to allow user code to be platform-independent
about file access, using the lws platform file operations underneath:
static inline lws_filefd_type
lws_plat_file_open(struct lws_plat_file_ops *fops, const char *filename,
unsigned long *filelen, int flags)
static inline int
lws_plat_file_close(struct lws_plat_file_ops *fops, lws_filefd_type fd)
static inline unsigned long
lws_plat_file_seek_cur(struct lws_plat_file_ops *fops, lws_filefd_type fd,
long offset_from_cur_pos)
static inline int
lws_plat_file_read(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
static inline int
lws_plat_file_write(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
There's example documentation and implementation in the test server.
Signed-off-by: Andy Green <andy.green@linaro.org>
2015-12-10 07:58:58 +08:00
|
|
|
|
2017-02-25 12:42:45 +08:00
|
|
|
fop_fd = malloc(sizeof(*fop_fd));
|
|
|
|
if (!fop_fd)
|
|
|
|
goto bail;
|
|
|
|
|
|
|
|
fop_fd->fops = fops;
|
|
|
|
fop_fd->fd = ret;
|
|
|
|
fop_fd->filesystem_priv = NULL; /* we don't use it */
|
2017-03-03 12:38:10 +08:00
|
|
|
fop_fd->flags = *flags;
|
|
|
|
fop_fd->len = GetFileSize(ret, NULL);
|
|
|
|
fop_fd->pos = 0;
|
2017-02-25 12:42:45 +08:00
|
|
|
|
|
|
|
return fop_fd;
|
|
|
|
|
|
|
|
bail:
|
|
|
|
return NULL;
|
lws_plat_fd implement platform default handlers
This is a rewrite of the patch from Soapyman here
https://github.com/warmcat/libwebsockets/pull/363
The main changes compared to Soapyman's original patch are
- There's no new stuff in the info struct user code does any overrides
it may want to do explicitly after lws_context_create returns
- User overrides for file ops can call through (subclass) to the original
platform implementation using lws_get_fops_plat()
- A typedef is provided for plat-specific fd type
- Public helpers are provided to allow user code to be platform-independent
about file access, using the lws platform file operations underneath:
static inline lws_filefd_type
lws_plat_file_open(struct lws_plat_file_ops *fops, const char *filename,
unsigned long *filelen, int flags)
static inline int
lws_plat_file_close(struct lws_plat_file_ops *fops, lws_filefd_type fd)
static inline unsigned long
lws_plat_file_seek_cur(struct lws_plat_file_ops *fops, lws_filefd_type fd,
long offset_from_cur_pos)
static inline int
lws_plat_file_read(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
static inline int
lws_plat_file_write(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
There's example documentation and implementation in the test server.
Signed-off-by: Andy Green <andy.green@linaro.org>
2015-12-10 07:58:58 +08:00
|
|
|
}
|
|
|
|
|
2017-03-01 14:28:56 +08:00
|
|
|
LWS_VISIBLE int
|
2017-03-03 12:38:10 +08:00
|
|
|
_lws_plat_file_close(lws_fop_fd_t *fop_fd)
|
lws_plat_fd implement platform default handlers
This is a rewrite of the patch from Soapyman here
https://github.com/warmcat/libwebsockets/pull/363
The main changes compared to Soapyman's original patch are
- There's no new stuff in the info struct user code does any overrides
it may want to do explicitly after lws_context_create returns
- User overrides for file ops can call through (subclass) to the original
platform implementation using lws_get_fops_plat()
- A typedef is provided for plat-specific fd type
- Public helpers are provided to allow user code to be platform-independent
about file access, using the lws platform file operations underneath:
static inline lws_filefd_type
lws_plat_file_open(struct lws_plat_file_ops *fops, const char *filename,
unsigned long *filelen, int flags)
static inline int
lws_plat_file_close(struct lws_plat_file_ops *fops, lws_filefd_type fd)
static inline unsigned long
lws_plat_file_seek_cur(struct lws_plat_file_ops *fops, lws_filefd_type fd,
long offset_from_cur_pos)
static inline int
lws_plat_file_read(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
static inline int
lws_plat_file_write(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
There's example documentation and implementation in the test server.
Signed-off-by: Andy Green <andy.green@linaro.org>
2015-12-10 07:58:58 +08:00
|
|
|
{
|
2017-03-03 12:38:10 +08:00
|
|
|
HANDLE fd = (*fop_fd)->fd;
|
2017-02-25 12:42:45 +08:00
|
|
|
|
2017-03-03 12:38:10 +08:00
|
|
|
free(*fop_fd);
|
|
|
|
*fop_fd = NULL;
|
2015-12-11 13:12:58 +08:00
|
|
|
|
lws_plat_fd implement platform default handlers
This is a rewrite of the patch from Soapyman here
https://github.com/warmcat/libwebsockets/pull/363
The main changes compared to Soapyman's original patch are
- There's no new stuff in the info struct user code does any overrides
it may want to do explicitly after lws_context_create returns
- User overrides for file ops can call through (subclass) to the original
platform implementation using lws_get_fops_plat()
- A typedef is provided for plat-specific fd type
- Public helpers are provided to allow user code to be platform-independent
about file access, using the lws platform file operations underneath:
static inline lws_filefd_type
lws_plat_file_open(struct lws_plat_file_ops *fops, const char *filename,
unsigned long *filelen, int flags)
static inline int
lws_plat_file_close(struct lws_plat_file_ops *fops, lws_filefd_type fd)
static inline unsigned long
lws_plat_file_seek_cur(struct lws_plat_file_ops *fops, lws_filefd_type fd,
long offset_from_cur_pos)
static inline int
lws_plat_file_read(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
static inline int
lws_plat_file_write(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
There's example documentation and implementation in the test server.
Signed-off-by: Andy Green <andy.green@linaro.org>
2015-12-10 07:58:58 +08:00
|
|
|
CloseHandle((HANDLE)fd);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-03-01 14:28:56 +08:00
|
|
|
LWS_VISIBLE lws_fileofs_t
|
2017-02-25 12:42:45 +08:00
|
|
|
_lws_plat_file_seek_cur(lws_fop_fd_t fop_fd, lws_fileofs_t offset)
|
lws_plat_fd implement platform default handlers
This is a rewrite of the patch from Soapyman here
https://github.com/warmcat/libwebsockets/pull/363
The main changes compared to Soapyman's original patch are
- There's no new stuff in the info struct user code does any overrides
it may want to do explicitly after lws_context_create returns
- User overrides for file ops can call through (subclass) to the original
platform implementation using lws_get_fops_plat()
- A typedef is provided for plat-specific fd type
- Public helpers are provided to allow user code to be platform-independent
about file access, using the lws platform file operations underneath:
static inline lws_filefd_type
lws_plat_file_open(struct lws_plat_file_ops *fops, const char *filename,
unsigned long *filelen, int flags)
static inline int
lws_plat_file_close(struct lws_plat_file_ops *fops, lws_filefd_type fd)
static inline unsigned long
lws_plat_file_seek_cur(struct lws_plat_file_ops *fops, lws_filefd_type fd,
long offset_from_cur_pos)
static inline int
lws_plat_file_read(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
static inline int
lws_plat_file_write(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
There's example documentation and implementation in the test server.
Signed-off-by: Andy Green <andy.green@linaro.org>
2015-12-10 07:58:58 +08:00
|
|
|
{
|
2017-02-25 12:42:45 +08:00
|
|
|
return SetFilePointer((HANDLE)fop_fd->fd, offset, NULL, FILE_CURRENT);
|
lws_plat_fd implement platform default handlers
This is a rewrite of the patch from Soapyman here
https://github.com/warmcat/libwebsockets/pull/363
The main changes compared to Soapyman's original patch are
- There's no new stuff in the info struct user code does any overrides
it may want to do explicitly after lws_context_create returns
- User overrides for file ops can call through (subclass) to the original
platform implementation using lws_get_fops_plat()
- A typedef is provided for plat-specific fd type
- Public helpers are provided to allow user code to be platform-independent
about file access, using the lws platform file operations underneath:
static inline lws_filefd_type
lws_plat_file_open(struct lws_plat_file_ops *fops, const char *filename,
unsigned long *filelen, int flags)
static inline int
lws_plat_file_close(struct lws_plat_file_ops *fops, lws_filefd_type fd)
static inline unsigned long
lws_plat_file_seek_cur(struct lws_plat_file_ops *fops, lws_filefd_type fd,
long offset_from_cur_pos)
static inline int
lws_plat_file_read(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
static inline int
lws_plat_file_write(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
There's example documentation and implementation in the test server.
Signed-off-by: Andy Green <andy.green@linaro.org>
2015-12-10 07:58:58 +08:00
|
|
|
}
|
|
|
|
|
2017-03-01 14:28:56 +08:00
|
|
|
LWS_VISIBLE int
|
2017-02-25 12:42:45 +08:00
|
|
|
_lws_plat_file_read(lws_fop_fd_t fop_fd, lws_filepos_t *amount,
|
|
|
|
uint8_t *buf, lws_filepos_t len)
|
lws_plat_fd implement platform default handlers
This is a rewrite of the patch from Soapyman here
https://github.com/warmcat/libwebsockets/pull/363
The main changes compared to Soapyman's original patch are
- There's no new stuff in the info struct user code does any overrides
it may want to do explicitly after lws_context_create returns
- User overrides for file ops can call through (subclass) to the original
platform implementation using lws_get_fops_plat()
- A typedef is provided for plat-specific fd type
- Public helpers are provided to allow user code to be platform-independent
about file access, using the lws platform file operations underneath:
static inline lws_filefd_type
lws_plat_file_open(struct lws_plat_file_ops *fops, const char *filename,
unsigned long *filelen, int flags)
static inline int
lws_plat_file_close(struct lws_plat_file_ops *fops, lws_filefd_type fd)
static inline unsigned long
lws_plat_file_seek_cur(struct lws_plat_file_ops *fops, lws_filefd_type fd,
long offset_from_cur_pos)
static inline int
lws_plat_file_read(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
static inline int
lws_plat_file_write(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
There's example documentation and implementation in the test server.
Signed-off-by: Andy Green <andy.green@linaro.org>
2015-12-10 07:58:58 +08:00
|
|
|
{
|
|
|
|
DWORD _amount;
|
|
|
|
|
2017-02-25 12:42:45 +08:00
|
|
|
if (!ReadFile((HANDLE)fop_fd->fd, buf, (DWORD)len, &_amount, NULL)) {
|
lws_plat_fd implement platform default handlers
This is a rewrite of the patch from Soapyman here
https://github.com/warmcat/libwebsockets/pull/363
The main changes compared to Soapyman's original patch are
- There's no new stuff in the info struct user code does any overrides
it may want to do explicitly after lws_context_create returns
- User overrides for file ops can call through (subclass) to the original
platform implementation using lws_get_fops_plat()
- A typedef is provided for plat-specific fd type
- Public helpers are provided to allow user code to be platform-independent
about file access, using the lws platform file operations underneath:
static inline lws_filefd_type
lws_plat_file_open(struct lws_plat_file_ops *fops, const char *filename,
unsigned long *filelen, int flags)
static inline int
lws_plat_file_close(struct lws_plat_file_ops *fops, lws_filefd_type fd)
static inline unsigned long
lws_plat_file_seek_cur(struct lws_plat_file_ops *fops, lws_filefd_type fd,
long offset_from_cur_pos)
static inline int
lws_plat_file_read(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
static inline int
lws_plat_file_write(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
There's example documentation and implementation in the test server.
Signed-off-by: Andy Green <andy.green@linaro.org>
2015-12-10 07:58:58 +08:00
|
|
|
*amount = 0;
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2017-03-03 12:38:10 +08:00
|
|
|
fop_fd->pos += _amount;
|
lws_plat_fd implement platform default handlers
This is a rewrite of the patch from Soapyman here
https://github.com/warmcat/libwebsockets/pull/363
The main changes compared to Soapyman's original patch are
- There's no new stuff in the info struct user code does any overrides
it may want to do explicitly after lws_context_create returns
- User overrides for file ops can call through (subclass) to the original
platform implementation using lws_get_fops_plat()
- A typedef is provided for plat-specific fd type
- Public helpers are provided to allow user code to be platform-independent
about file access, using the lws platform file operations underneath:
static inline lws_filefd_type
lws_plat_file_open(struct lws_plat_file_ops *fops, const char *filename,
unsigned long *filelen, int flags)
static inline int
lws_plat_file_close(struct lws_plat_file_ops *fops, lws_filefd_type fd)
static inline unsigned long
lws_plat_file_seek_cur(struct lws_plat_file_ops *fops, lws_filefd_type fd,
long offset_from_cur_pos)
static inline int
lws_plat_file_read(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
static inline int
lws_plat_file_write(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
There's example documentation and implementation in the test server.
Signed-off-by: Andy Green <andy.green@linaro.org>
2015-12-10 07:58:58 +08:00
|
|
|
*amount = (unsigned long)_amount;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-03-01 14:28:56 +08:00
|
|
|
LWS_VISIBLE int
|
2017-02-25 12:42:45 +08:00
|
|
|
_lws_plat_file_write(lws_fop_fd_t fop_fd, lws_filepos_t *amount,
|
|
|
|
uint8_t* buf, lws_filepos_t len)
|
lws_plat_fd implement platform default handlers
This is a rewrite of the patch from Soapyman here
https://github.com/warmcat/libwebsockets/pull/363
The main changes compared to Soapyman's original patch are
- There's no new stuff in the info struct user code does any overrides
it may want to do explicitly after lws_context_create returns
- User overrides for file ops can call through (subclass) to the original
platform implementation using lws_get_fops_plat()
- A typedef is provided for plat-specific fd type
- Public helpers are provided to allow user code to be platform-independent
about file access, using the lws platform file operations underneath:
static inline lws_filefd_type
lws_plat_file_open(struct lws_plat_file_ops *fops, const char *filename,
unsigned long *filelen, int flags)
static inline int
lws_plat_file_close(struct lws_plat_file_ops *fops, lws_filefd_type fd)
static inline unsigned long
lws_plat_file_seek_cur(struct lws_plat_file_ops *fops, lws_filefd_type fd,
long offset_from_cur_pos)
static inline int
lws_plat_file_read(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
static inline int
lws_plat_file_write(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
There's example documentation and implementation in the test server.
Signed-off-by: Andy Green <andy.green@linaro.org>
2015-12-10 07:58:58 +08:00
|
|
|
{
|
2017-02-25 12:42:45 +08:00
|
|
|
(void)fop_fd;
|
2015-12-11 13:12:58 +08:00
|
|
|
(void)amount;
|
|
|
|
(void)buf;
|
|
|
|
(void)len;
|
|
|
|
|
2017-03-03 12:38:10 +08:00
|
|
|
fop_fd->pos += len;
|
|
|
|
|
2015-12-11 13:12:58 +08:00
|
|
|
lwsl_err("%s: not implemented yet on this platform\n", __func__);
|
2015-12-14 08:52:03 +08:00
|
|
|
|
lws_plat_fd implement platform default handlers
This is a rewrite of the patch from Soapyman here
https://github.com/warmcat/libwebsockets/pull/363
The main changes compared to Soapyman's original patch are
- There's no new stuff in the info struct user code does any overrides
it may want to do explicitly after lws_context_create returns
- User overrides for file ops can call through (subclass) to the original
platform implementation using lws_get_fops_plat()
- A typedef is provided for plat-specific fd type
- Public helpers are provided to allow user code to be platform-independent
about file access, using the lws platform file operations underneath:
static inline lws_filefd_type
lws_plat_file_open(struct lws_plat_file_ops *fops, const char *filename,
unsigned long *filelen, int flags)
static inline int
lws_plat_file_close(struct lws_plat_file_ops *fops, lws_filefd_type fd)
static inline unsigned long
lws_plat_file_seek_cur(struct lws_plat_file_ops *fops, lws_filefd_type fd,
long offset_from_cur_pos)
static inline int
lws_plat_file_read(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
static inline int
lws_plat_file_write(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
There's example documentation and implementation in the test server.
Signed-off-by: Andy Green <andy.green@linaro.org>
2015-12-10 07:58:58 +08:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
LWS_VISIBLE int
|
|
|
|
lws_plat_init(struct lws_context *context,
|
2016-07-11 21:17:21 +08:00
|
|
|
struct lws_context_creation_info *info)
|
lws_plat_fd implement platform default handlers
This is a rewrite of the patch from Soapyman here
https://github.com/warmcat/libwebsockets/pull/363
The main changes compared to Soapyman's original patch are
- There's no new stuff in the info struct user code does any overrides
it may want to do explicitly after lws_context_create returns
- User overrides for file ops can call through (subclass) to the original
platform implementation using lws_get_fops_plat()
- A typedef is provided for plat-specific fd type
- Public helpers are provided to allow user code to be platform-independent
about file access, using the lws platform file operations underneath:
static inline lws_filefd_type
lws_plat_file_open(struct lws_plat_file_ops *fops, const char *filename,
unsigned long *filelen, int flags)
static inline int
lws_plat_file_close(struct lws_plat_file_ops *fops, lws_filefd_type fd)
static inline unsigned long
lws_plat_file_seek_cur(struct lws_plat_file_ops *fops, lws_filefd_type fd,
long offset_from_cur_pos)
static inline int
lws_plat_file_read(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
static inline int
lws_plat_file_write(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
There's example documentation and implementation in the test server.
Signed-off-by: Andy Green <andy.green@linaro.org>
2015-12-10 07:58:58 +08:00
|
|
|
{
|
2016-01-19 03:34:24 +08:00
|
|
|
struct lws_context_per_thread *pt = &context->pt[0];
|
|
|
|
int i, n = context->count_threads;
|
lws_plat_fd implement platform default handlers
This is a rewrite of the patch from Soapyman here
https://github.com/warmcat/libwebsockets/pull/363
The main changes compared to Soapyman's original patch are
- There's no new stuff in the info struct user code does any overrides
it may want to do explicitly after lws_context_create returns
- User overrides for file ops can call through (subclass) to the original
platform implementation using lws_get_fops_plat()
- A typedef is provided for plat-specific fd type
- Public helpers are provided to allow user code to be platform-independent
about file access, using the lws platform file operations underneath:
static inline lws_filefd_type
lws_plat_file_open(struct lws_plat_file_ops *fops, const char *filename,
unsigned long *filelen, int flags)
static inline int
lws_plat_file_close(struct lws_plat_file_ops *fops, lws_filefd_type fd)
static inline unsigned long
lws_plat_file_seek_cur(struct lws_plat_file_ops *fops, lws_filefd_type fd,
long offset_from_cur_pos)
static inline int
lws_plat_file_read(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
static inline int
lws_plat_file_write(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
There's example documentation and implementation in the test server.
Signed-off-by: Andy Green <andy.green@linaro.org>
2015-12-10 07:58:58 +08:00
|
|
|
|
|
|
|
for (i = 0; i < FD_HASHTABLE_MODULUS; i++) {
|
|
|
|
context->fd_hashtable[i].wsi =
|
|
|
|
lws_zalloc(sizeof(struct lws*) * context->max_fds);
|
|
|
|
|
|
|
|
if (!context->fd_hashtable[i].wsi)
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2016-01-19 03:34:24 +08:00
|
|
|
while (n--) {
|
|
|
|
pt->events = lws_malloc(sizeof(WSAEVENT) *
|
|
|
|
(context->fd_limit_per_thread + 1));
|
|
|
|
if (pt->events == NULL) {
|
|
|
|
lwsl_err("Unable to allocate events array for %d connections\n",
|
|
|
|
context->fd_limit_per_thread + 1);
|
|
|
|
return 1;
|
|
|
|
}
|
lws_plat_fd implement platform default handlers
This is a rewrite of the patch from Soapyman here
https://github.com/warmcat/libwebsockets/pull/363
The main changes compared to Soapyman's original patch are
- There's no new stuff in the info struct user code does any overrides
it may want to do explicitly after lws_context_create returns
- User overrides for file ops can call through (subclass) to the original
platform implementation using lws_get_fops_plat()
- A typedef is provided for plat-specific fd type
- Public helpers are provided to allow user code to be platform-independent
about file access, using the lws platform file operations underneath:
static inline lws_filefd_type
lws_plat_file_open(struct lws_plat_file_ops *fops, const char *filename,
unsigned long *filelen, int flags)
static inline int
lws_plat_file_close(struct lws_plat_file_ops *fops, lws_filefd_type fd)
static inline unsigned long
lws_plat_file_seek_cur(struct lws_plat_file_ops *fops, lws_filefd_type fd,
long offset_from_cur_pos)
static inline int
lws_plat_file_read(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
static inline int
lws_plat_file_write(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
There's example documentation and implementation in the test server.
Signed-off-by: Andy Green <andy.green@linaro.org>
2015-12-10 07:58:58 +08:00
|
|
|
|
2016-01-19 03:34:24 +08:00
|
|
|
pt->fds_count = 0;
|
|
|
|
pt->events[0] = WSACreateEvent();
|
|
|
|
|
|
|
|
pt++;
|
|
|
|
}
|
lws_plat_fd implement platform default handlers
This is a rewrite of the patch from Soapyman here
https://github.com/warmcat/libwebsockets/pull/363
The main changes compared to Soapyman's original patch are
- There's no new stuff in the info struct user code does any overrides
it may want to do explicitly after lws_context_create returns
- User overrides for file ops can call through (subclass) to the original
platform implementation using lws_get_fops_plat()
- A typedef is provided for plat-specific fd type
- Public helpers are provided to allow user code to be platform-independent
about file access, using the lws platform file operations underneath:
static inline lws_filefd_type
lws_plat_file_open(struct lws_plat_file_ops *fops, const char *filename,
unsigned long *filelen, int flags)
static inline int
lws_plat_file_close(struct lws_plat_file_ops *fops, lws_filefd_type fd)
static inline unsigned long
lws_plat_file_seek_cur(struct lws_plat_file_ops *fops, lws_filefd_type fd,
long offset_from_cur_pos)
static inline int
lws_plat_file_read(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
static inline int
lws_plat_file_write(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
There's example documentation and implementation in the test server.
Signed-off-by: Andy Green <andy.green@linaro.org>
2015-12-10 07:58:58 +08:00
|
|
|
|
|
|
|
context->fd_random = 0;
|
|
|
|
|
2016-05-25 19:42:35 +08:00
|
|
|
#ifdef LWS_WITH_PLUGINS
|
|
|
|
if (info->plugin_dirs)
|
|
|
|
lws_plat_plugins_init(context, info->plugin_dirs);
|
|
|
|
#endif
|
|
|
|
|
lws_plat_fd implement platform default handlers
This is a rewrite of the patch from Soapyman here
https://github.com/warmcat/libwebsockets/pull/363
The main changes compared to Soapyman's original patch are
- There's no new stuff in the info struct user code does any overrides
it may want to do explicitly after lws_context_create returns
- User overrides for file ops can call through (subclass) to the original
platform implementation using lws_get_fops_plat()
- A typedef is provided for plat-specific fd type
- Public helpers are provided to allow user code to be platform-independent
about file access, using the lws platform file operations underneath:
static inline lws_filefd_type
lws_plat_file_open(struct lws_plat_file_ops *fops, const char *filename,
unsigned long *filelen, int flags)
static inline int
lws_plat_file_close(struct lws_plat_file_ops *fops, lws_filefd_type fd)
static inline unsigned long
lws_plat_file_seek_cur(struct lws_plat_file_ops *fops, lws_filefd_type fd,
long offset_from_cur_pos)
static inline int
lws_plat_file_read(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
static inline int
lws_plat_file_write(struct lws_plat_file_ops *fops, lws_filefd_type fd,
unsigned long *amount, unsigned char *buf, unsigned long len)
There's example documentation and implementation in the test server.
Signed-off-by: Andy Green <andy.green@linaro.org>
2015-12-10 07:58:58 +08:00
|
|
|
return 0;
|
|
|
|
}
|
context deprecation
1) This makes lwsws run a parent process with the original permissions.
But this process is only able to respond to SIGHUP, it doesn't do anything
else.
2) You can send this parent process a SIGHUP now to cause it to
- close listening sockets in existing lwsws processes
- mark those processes as to exit when the number of active connections
on the falls to zero
- spawn a fresh child process from scratch, using latest configuration
file content, latest plugins, etc. It can now reopen listening sockets
if it chooses to, or open different listen ports or whatever.
Notes:
1) lws_context_destroy() has been split into two pieces... the reason for
the split is the first part closes the per-vhost protocols, but since
they may have created libuv objects in the per-vhost protocol storage,
these cannot be freed until after the loop has been run.
That's the purpose of the second part of the context destruction,
lws_context_destroy2().
For compatibility, if you are not using libuv, the first part calls the
second part. However if you are using libuv, you must now call the
second part from your own main.c after the first part.
2016-12-16 07:37:43 +08:00
|
|
|
|
|
|
|
|
|
|
|
int kill(int pid, int sig)
|
|
|
|
{
|
|
|
|
lwsl_err("Sorry Windows doesn't support kill().");
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
int fork(void)
|
|
|
|
{
|
|
|
|
lwsl_err("Sorry Windows doesn't support fork().");
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|