close(fd);
} else {
server = afb_stub_ws_create_server(fdev, &apiws->uri[apiws->offapi], apiws->apiset);
- if (!server)
+ if (server)
+ afb_stub_ws_set_on_hangup(server, afb_stub_ws_unref);
+ else
ERROR("can't serve accepted connection to %s: %m", apiws->uri);
}
}
if ((revents & EPOLLIN) != 0)
api_ws_server_accept(apiws);
- if ((revents & EPOLLHUP) != 0)
+ else if ((revents & EPOLLHUP) != 0)
api_ws_server_connect(apiws);
}
/* count of references */
int refcount;
- /* file descriptor */
- struct fdev *fdev;
-
/* resource control */
pthread_mutex_t mutex;
free(cd);
}
- if (protows->fdev) {
- fdev_unref(protows->fdev);
- protows->fdev = 0;
+ if (protows->ws) {
+ afb_ws_destroy(protows->ws);
+ protows->ws = 0;
if (protows->on_hangup)
protows->on_hangup(protows->closure);
}
fcntl(fdev_fd(fdev), F_SETFL, O_NONBLOCK);
protows->ws = afb_ws_create(fdev, itf, protows);
if (protows->ws != NULL) {
- protows->fdev = fdev;
protows->refcount = 1;
protows->closure = closure;
protows->server_itf = itfs;
{
if (protows && !__atomic_sub_fetch(&protows->refcount, 1, __ATOMIC_RELAXED)) {
afb_proto_ws_hangup(protows);
- afb_ws_destroy(protows->ws);
pthread_mutex_destroy(&protows->mutex);
free(protows);
}
void afb_proto_ws_hangup(struct afb_proto_ws *protows)
{
- afb_ws_hangup(protows->ws);
+ if (protows->ws)
+ afb_ws_hangup(protows->ws);
}
void afb_proto_ws_on_hangup(struct afb_proto_ws *protows, void (*on_hangup)(void *closure))
struct websock *wsi = ws->ws;
if (wsi != NULL) {
ws->ws = NULL;
+ fdev_set_callback(ws->fdev, NULL, 0);
fdev_unref(ws->fdev);
websock_destroy(wsi);
free(ws->buffer.buffer);
{
if ((revents & EPOLLIN) != 0)
aws_on_readable(ws);
- if ((revents & EPOLLHUP) != 0)
+ else if ((revents & EPOLLHUP) != 0)
afb_ws_hangup(ws);
}
{
if ((revents & EPOLLIN) != 0)
accept_supervision_link((int)(intptr_t)closure);
- if ((revents & EPOLLHUP) != 0) {
+ else if ((revents & EPOLLHUP) != 0) {
ERROR("supervision socket closed");
exit(1);
}