/* Not locked. */
isc_socket_t common;
isc__socketmgr_t *manager;
- isc_mutex_t lock;
isc_sockettype_t type;
const isc_statscounter_t *statsindex;
isc_refcount_t references;
char name[16];
void * tag;
+ isc_mutex_t rdlock;
ISC_LIST(isc_socketevent_t) send_list;
ISC_LIST(isc_socketevent_t) recv_list;
ISC_LIST(isc_socket_newconnev_t) accept_list;
ISC_LIST(isc_socket_connev_t) connect_list;
+ isc_mutex_t wrlock;
isc_sockaddr_t peer_address; /* remote address */
/*
* Initialize the lock.
*/
- isc_mutex_init(&sock->lock);
+ isc_mutex_init(&sock->rdlock);
+ isc_mutex_init(&sock->wrlock);
sock->common.magic = ISCAPI_SOCKET_MAGIC;
sock->common.impmagic = SOCKET_MAGIC;
sock->common.magic = 0;
sock->common.impmagic = 0;
- isc_mutex_destroy(&sock->lock);
+ isc_mutex_destroy(&sock->rdlock);
+ isc_mutex_destroy(&sock->wrlock);
isc_mem_put(sock->manager->mctx, sock, sizeof(*sock));
fflush(stdout);
REQUIRE(VALID_SOCKET(sock));
- LOCK(&sock->lock);
+ LOCK(&sock->rdlock);
+ LOCK(&sock->wrlock);
REQUIRE(sock->fd >= 0 && sock->fd < (int)sock->manager->maxsocks);
sock->bound = 0;
isc_sockaddr_any(&sock->peer_address);
- UNLOCK(&sock->lock);
+ UNLOCK(&sock->wrlock);
+ UNLOCK(&sock->rdlock);
socketclose(thread, sock, fd);
INSIST(VALID_SOCKET(sock));
- LOCK(&sock->lock);
+ LOCK(&sock->rdlock);
socket_log(sock, NULL, TRACE,
isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_ACCEPTLOCK,
"internal_accept called, locked socket");
dev = ISC_LIST_HEAD(sock->accept_list);
if (dev == NULL) {
unwatch_fd(thread, sock->fd, SELECT_POKE_ACCEPT);
- UNLOCK(&sock->lock);
+ UNLOCK(&sock->rdlock);
return;
}
unwatch_fd(thread, sock->fd,
SELECT_POKE_ACCEPT);
- UNLOCK(&sock->lock);
+ UNLOCK(&sock->rdlock);
if (fd != -1) {
result = make_nonblock(fd);
soft_error:
watch_fd(thread, sock->fd, SELECT_POKE_ACCEPT);
- UNLOCK(&sock->lock);
+ UNLOCK(&sock->rdlock);
inc_stats(manager->stats, sock->statsindex[STATID_ACCEPTFAIL]);
return;
INSIST(VALID_SOCKET(sock));
- LOCK(&sock->lock);
+ LOCK(&sock->rdlock);
dev = ISC_LIST_HEAD(sock->recv_list);
if (dev == NULL) {
goto finish;
unwatch_fd(&sock->manager->threads[sock->threadid], sock->fd,
SELECT_POKE_READ);
}
- UNLOCK(&sock->lock);
+ UNLOCK(&sock->rdlock);
}
static void
INSIST(VALID_SOCKET(sock));
- LOCK(&sock->lock);
+ LOCK(&sock->wrlock);
dev = ISC_LIST_HEAD(sock->send_list);
if (dev == NULL) {
goto finish;
unwatch_fd(&sock->manager->threads[sock->threadid],
sock->fd, SELECT_POKE_WRITE);
}
- UNLOCK(&sock->lock);
+ UNLOCK(&sock->wrlock);
}
/*
if (sock->type == isc_sockettype_udp) {
io_state = doio_recv(sock, dev);
} else {
- LOCK(&sock->lock);
+ LOCK(&sock->rdlock);
have_lock = true;
if (ISC_LIST_EMPTY(sock->recv_list)) {
dev->attributes |= ISC_SOCKEVENTATTR_ATTACHED;
if (!have_lock) {
- LOCK(&sock->lock);
+ LOCK(&sock->rdlock);
have_lock = true;
}
}
if (have_lock) {
- UNLOCK(&sock->lock);
+ UNLOCK(&sock->rdlock);
}
return (result);
if (sock->type == isc_sockettype_udp) {
io_state = doio_send(sock, dev);
} else {
- LOCK(&sock->lock);
+ LOCK(&sock->wrlock);
have_lock = true;
if (ISC_LIST_EMPTY(sock->send_list)) {
dev->attributes |= ISC_SOCKEVENTATTR_ATTACHED;
if (!have_lock) {
- LOCK(&sock->lock);
+ LOCK(&sock->wrlock);
have_lock = true;
}
}
if (have_lock) {
- UNLOCK(&sock->lock);
+ UNLOCK(&sock->wrlock);
}
return (result);
REQUIRE(VALID_SOCKET(sock));
- LOCK(&sock->lock);
+ LOCK(&sock->rdlock);
INSIST(!sock->bound);
INSIST(!sock->dupped);
if (sock->pf != sockaddr->type.sa.sa_family) {
- UNLOCK(&sock->lock);
+ UNLOCK(&sock->rdlock);
return (ISC_R_FAMILYMISMATCH);
}
inc_stats(sock->manager->stats,
sock->statsindex[STATID_BINDFAIL]);
- UNLOCK(&sock->lock);
+ UNLOCK(&sock->rdlock);
switch (errno) {
case EACCES:
return (ISC_R_NOPERM);
isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_BOUND, "bound");
sock->bound = 1;
- UNLOCK(&sock->lock);
+ UNLOCK(&sock->rdlock);
return (ISC_R_SUCCESS);
}
REQUIRE(VALID_SOCKET(sock));
- LOCK(&sock->lock);
+ LOCK(&sock->rdlock);
REQUIRE(!sock->listener);
REQUIRE(sock->bound);
backlog = SOMAXCONN;
if (listen(sock->fd, (int)backlog) < 0) {
- UNLOCK(&sock->lock);
+ UNLOCK(&sock->rdlock);
strerror_r(errno, strbuf, sizeof(strbuf));
UNEXPECTED_ERROR(__FILE__, __LINE__, "listen: %s", strbuf);
sock->listener = 1;
- UNLOCK(&sock->lock);
+ UNLOCK(&sock->rdlock);
return (ISC_R_SUCCESS);
}
manager = sock->manager;
REQUIRE(VALID_MANAGER(manager));
- LOCK(&sock->lock);
+ LOCK(&sock->rdlock);
REQUIRE(sock->listener);
isc_event_allocate(manager->mctx, task, ISC_SOCKEVENT_NEWCONN,
action, arg, sizeof(*dev));
if (dev == NULL) {
- UNLOCK(&sock->lock);
+ UNLOCK(&sock->rdlock);
return (ISC_R_NOMEMORY);
}
ISC_LINK_INIT(dev, ev_link);
result = allocate_socket(manager, sock->type, &nsock);
if (result != ISC_R_SUCCESS) {
isc_event_free(ISC_EVENT_PTR(&dev));
- UNLOCK(&sock->lock);
+ UNLOCK(&sock->rdlock);
return (result);
}
free_socket(&nsock);
isc_task_detach(&ntask);
isc_event_free(ISC_EVENT_PTR(&dev));
- UNLOCK(&sock->lock);
+ UNLOCK(&sock->rdlock);
return (ISC_R_SHUTTINGDOWN);
}
isc_refcount_increment(&nsock->references);
select_poke(manager, sock->threadid, sock->fd,
SELECT_POKE_ACCEPT);
}
- UNLOCK(&sock->lock);
+ UNLOCK(&sock->rdlock);
return (ISC_R_SUCCESS);
}
if (isc_sockaddr_ismulticast(addr))
return (ISC_R_MULTICAST);
- LOCK(&sock->lock);
+ LOCK(&sock->wrlock);
dev = (isc_socket_connev_t *)isc_event_allocate(manager->mctx, sock,
ISC_SOCKEVENT_CONNECT,
action, arg,
sizeof(*dev));
if (dev == NULL) {
- UNLOCK(&sock->lock);
+ UNLOCK(&sock->wrlock);
return (ISC_R_NOMEMORY);
}
ISC_LINK_INIT(dev, ev_link);
dev->result = ISC_R_SUCCESS;
isc_task_sendto(task, ISC_EVENT_PTR(&dev), sock->threadid);
- UNLOCK(&sock->lock);
+ UNLOCK(&sock->wrlock);
return (ISC_R_SUCCESS);
}
UNEXPECTED_ERROR(__FILE__, __LINE__, "connect(%s) %d/%s",
addrbuf, errno, strbuf);
- UNLOCK(&sock->lock);
+ UNLOCK(&sock->wrlock);
inc_stats(sock->manager->stats,
sock->statsindex[STATID_CONNECTFAIL]);
isc_event_free(ISC_EVENT_PTR(&dev));
sock->connected = 0;
isc_task_sendto(task, ISC_EVENT_PTR(&dev), sock->threadid);
- UNLOCK(&sock->lock);
+ UNLOCK(&sock->wrlock);
inc_stats(sock->manager->stats,
sock->statsindex[STATID_CONNECTFAIL]);
return (ISC_R_SUCCESS);
dev->result = ISC_R_SUCCESS;
isc_task_sendto(task, ISC_EVENT_PTR(&dev), sock->threadid);
- UNLOCK(&sock->lock);
+ UNLOCK(&sock->wrlock);
inc_stats(sock->manager->stats,
sock->statsindex[STATID_CONNECT]);
SELECT_POKE_CONNECT);
}
- UNLOCK(&sock->lock);
+ UNLOCK(&sock->wrlock);
return (ISC_R_SUCCESS);
}
INSIST(VALID_SOCKET(sock));
- LOCK(&sock->lock);
+ LOCK(&sock->wrlock);
/*
* Get the first item off the connect list.
*/
if (SOFT_ERROR(errno) || errno == EINPROGRESS) {
sock->connecting = 1;
- UNLOCK(&sock->lock);
+ UNLOCK(&sock->wrlock);
return;
}
unwatch_fd(&sock->manager->threads[sock->threadid], sock->fd,
SELECT_POKE_CONNECT);
- UNLOCK(&sock->lock);
+ UNLOCK(&sock->wrlock);
}
isc_result_t
REQUIRE(VALID_SOCKET(sock));
REQUIRE(addressp != NULL);
- LOCK(&sock->lock);
+ LOCK(&sock->rdlock);
+ LOCK(&sock->wrlock);
if (sock->connected) {
*addressp = sock->peer_address;
result = ISC_R_NOTCONNECTED;
}
- UNLOCK(&sock->lock);
+ UNLOCK(&sock->wrlock);
+ UNLOCK(&sock->rdlock);
return (result);
}
REQUIRE(VALID_SOCKET(sock));
REQUIRE(addressp != NULL);
- LOCK(&sock->lock);
+ LOCK(&sock->rdlock);
+ LOCK(&sock->wrlock);
if (!sock->bound) {
result = ISC_R_NOTBOUND;
addressp->length = (unsigned int)len;
out:
- UNLOCK(&sock->lock);
+ UNLOCK(&sock->wrlock);
+ UNLOCK(&sock->rdlock);
return (result);
}
if (how == 0)
return;
- LOCK(&sock->lock);
+ LOCK(&sock->rdlock);
+ LOCK(&sock->wrlock);
/*
* All of these do the same thing, more or less.
}
}
- UNLOCK(&sock->lock);
+ UNLOCK(&sock->wrlock);
+ UNLOCK(&sock->rdlock);
}
isc_sockettype_t
REQUIRE(VALID_SOCKET(sock));
- LOCK(&sock->lock);
+ LOCK(&sock->rdlock);
+ LOCK(&sock->wrlock);
strlcpy(sock->name, name, sizeof(sock->name));
sock->tag = tag;
- UNLOCK(&sock->lock);
+ UNLOCK(&sock->wrlock);
+ UNLOCK(&sock->rdlock);
}
const char *
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "sockets"));
sock = ISC_LIST_HEAD(mgr->socklist);
while (sock != NULL) {
- LOCK(&sock->lock);
+ LOCK(&sock->rdlock);
+ LOCK(&sock->wrlock);
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "socket"));
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "id"));
TRY0(xmlTextWriterEndElement(writer)); /* socket */
- UNLOCK(&sock->lock);
+ UNLOCK(&sock->wrlock);
+ UNLOCK(&sock->rdlock);
sock = ISC_LIST_NEXT(sock, link);
}
TRY0(xmlTextWriterEndElement(writer)); /* sockets */
error:
- if (sock != NULL)
- UNLOCK(&sock->lock);
-
+ if (sock != NULL) {
+ UNLOCK(&sock->wrlock);
+ UNLOCK(&sock->rdlock);
+ }
UNLOCK(&mgr->lock);
return (xmlrc);
CHECKMEM(entry);
json_object_array_add(array, entry);
- LOCK(&sock->lock);
+ LOCK(&sock->rdlock);
+ LOCK(&sock->wrlock);
snprintf(buf, sizeof(buf), "%p", sock);
obj = json_object_new_string(buf);
json_object_array_add(states, obj);
}
- UNLOCK(&sock->lock);
+ UNLOCK(&sock->wrlock);
+ UNLOCK(&sock->rdlock);
sock = ISC_LIST_NEXT(sock, link);
}
if (array != NULL)
json_object_put(array);
- if (sock != NULL)
- UNLOCK(&sock->lock);
-
+ if (sock != NULL) {
+ UNLOCK(&sock->wrlock);
+ UNLOCK(&sock->rdlock);
+ }
UNLOCK(&mgr->lock);
return (result);