Author: tross
Date: Fri Dec 5 21:03:47 2014
New Revision: 1643431
URL: http://svn.apache.org/r1643431
Log:
DISPATCH-78 - Fixed a thread-safety violation in the driver related to failed
connections.
This fixes the problem outlined in the Jira.
Modified:
qpid/dispatch/trunk/include/qpid/dispatch/driver.h
qpid/dispatch/trunk/src/posix/driver.c
qpid/dispatch/trunk/src/server.c
Modified: qpid/dispatch/trunk/include/qpid/dispatch/driver.h
URL:
http://svn.apache.org/viewvc/qpid/dispatch/trunk/include/qpid/dispatch/driver.h?rev=1643431&r1=1643430&r2=1643431&view=diff
==============================================================================
--- qpid/dispatch/trunk/include/qpid/dispatch/driver.h (original)
+++ qpid/dispatch/trunk/include/qpid/dispatch/driver.h Fri Dec 5 21:03:47 2014
@@ -330,6 +330,9 @@ void qdpn_connector_close(qdpn_connector
*/
bool qdpn_connector_closed(qdpn_connector_t *connector);
+bool qdpn_connector_failed(qdpn_connector_t *connector);
+
+
/** Destructor for the given connector.
*
* Assumes the connector's socket has been closed prior to call.
Modified: qpid/dispatch/trunk/src/posix/driver.c
URL:
http://svn.apache.org/viewvc/qpid/dispatch/trunk/src/posix/driver.c?rev=1643431&r1=1643430&r2=1643431&view=diff
==============================================================================
--- qpid/dispatch/trunk/src/posix/driver.c (original)
+++ qpid/dispatch/trunk/src/posix/driver.c Fri Dec 5 21:03:47 2014
@@ -97,6 +97,7 @@ struct qdpn_connector_t {
bool pending_tick;
bool pending_read;
bool pending_write;
+ bool socket_error;
bool closed;
bool input_done;
bool output_done;
@@ -351,6 +352,7 @@ qdpn_connector_t *qdpn_connector_fd(qdpn
c->pending_tick = false;
c->pending_read = false;
c->pending_write = false;
+ c->socket_error = false;
c->name[0] = '\0';
c->idx = 0;
c->fd = fd;
@@ -455,8 +457,10 @@ void qdpn_connector_close(qdpn_connector
ctor->status = 0;
if (close(ctor->fd) == -1)
perror("close");
- ctor->closed = true;
- ctor->driver->closed_count++;
+ if (!ctor->closed) {
+ ctor->closed = true;
+ ctor->driver->closed_count++;
+ }
}
bool qdpn_connector_closed(qdpn_connector_t *ctor)
@@ -464,6 +468,11 @@ bool qdpn_connector_closed(qdpn_connecto
return ctor ? ctor->closed : true;
}
+bool qdpn_connector_failed(qdpn_connector_t *ctor)
+{
+ return ctor ? ctor->socket_error : true;
+}
+
void qdpn_connector_free(qdpn_connector_t *ctor)
{
if (!ctor) return;
@@ -775,7 +784,7 @@ int qdpn_driver_wait_3(qdpn_driver_t *d)
c->pending_write = (idx && d->fds[idx].revents & POLLOUT);
c->pending_tick = (c->wakeup && c->wakeup <= now);
if (idx && d->fds[idx].revents & POLLERR)
- qdpn_connector_close(c);
+ c->socket_error = true;
else if (idx && (d->fds[idx].revents & POLLHUP)) {
if (c->trace & (PN_TRACE_FRM | PN_TRACE_RAW | PN_TRACE_DRV)) {
fprintf(stderr, "hangup on connector %s\n", c->name);
@@ -847,9 +856,8 @@ qdpn_connector_t *qdpn_driver_connector(
qdpn_connector_t *c = d->connector_next;
d->connector_next = DEQ_NEXT(c);
- if (c->closed || c->pending_read || c->pending_write ||
c->pending_tick) {
+ if (c->closed || c->pending_read || c->pending_write ||
c->pending_tick || c->socket_error)
return c;
- }
}
return NULL;
Modified: qpid/dispatch/trunk/src/server.c
URL:
http://svn.apache.org/viewvc/qpid/dispatch/trunk/src/server.c?rev=1643431&r1=1643430&r2=1643431&view=diff
==============================================================================
--- qpid/dispatch/trunk/src/server.c (original)
+++ qpid/dispatch/trunk/src/server.c Fri Dec 5 21:03:47 2014
@@ -535,7 +535,12 @@ static void *thread_run(void *arg)
// Process the connector that we now have exclusive access to.
//
if (cxtr) {
- int work_done = process_connector(qd_server, cxtr);
+ int work_done = 1;
+
+ if (qdpn_connector_failed(cxtr))
+ qdpn_connector_close(cxtr);
+ else
+ work_done = process_connector(qd_server, cxtr);
//
// Check to see if the connector was closed during processing
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]