Re: [PATCH] Properly lock pending_semops

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



ACK

Fabio

On 3/18/2013 10:23 AM, Jan Friesse wrote:
> pending_semops variable can be changed in two threads. One is actual IPC
> connection and second is coropoll. It's really scholar example of race
> (one thread doing i++, second doing i--). If socket is full, it can
> happen that IPC will increase value and coropoll will decrease,
> resulting in unpredictable value. This means, that client IPC can be
> informed about more messages then really available, resulting
> in reading of garbage messages in library dispatch function.
> 
> Solution is to properly lock variable.
> 
> Signed-off-by: Jan Friesse <jfriesse@xxxxxxxxxx>
> ---
>  exec/coroipcs.c |   27 +++++++++++++++------------
>  1 files changed, 15 insertions(+), 12 deletions(-)
> 
> diff --git a/exec/coroipcs.c b/exec/coroipcs.c
> index 36d18a4..a5c3248 100644
> --- a/exec/coroipcs.c
> +++ b/exec/coroipcs.c
> @@ -140,6 +140,7 @@ struct conn_info {
>  	key_t semkey;
>  #endif
>  	unsigned int pending_semops;
> +	pthread_mutex_t pending_semops_mutex;
>  	pthread_mutex_t mutex;
>  	struct control_buffer *control_buffer;
>  	char *request_buffer;
> @@ -1265,7 +1266,9 @@ static void msg_send (void *conn, const struct iovec *iov, unsigned int iov_len,
>  	buf = list_empty (&conn_info->outq_head);
>  	res = send (conn_info->fd, &buf, 1, MSG_NOSIGNAL);
>  	if (res != 1) {
> +		pthread_mutex_lock(&conn_info->pending_semops_mutex);
>  		conn_info->pending_semops += 1;
> +		pthread_mutex_unlock(&conn_info->pending_semops_mutex);
>  		if (conn_info->poll_state == POLL_STATE_IN) {
>  			conn_info->poll_state = POLL_STATE_INOUT;
>  			api->poll_dispatch_modify (conn_info->fd,
> @@ -1648,6 +1651,7 @@ int coroipcs_handler_dispatch (
>  		}
>  
>  		pthread_mutex_init (&conn_info->mutex, NULL);
> +		pthread_mutex_init (&conn_info->pending_semops_mutex, NULL);
>  		req_setup = (mar_req_setup_t *)conn_info->setup_msg;
>  		/*
>  		 * Is the service registered ?
> @@ -1784,22 +1788,21 @@ int coroipcs_handler_dispatch (
>  	}
>  
>  	if (revent & POLLOUT) {
> -		int psop = conn_info->pending_semops;
> -		int i;
> -
> -		assert (psop != 0);
> -		for (i = 0; i < psop; i++) {
> -			res = send (conn_info->fd, &buf, 1, MSG_NOSIGNAL);
> -			if (res != 1) {
> -				return (0);
> -			} else {
> -				conn_info->pending_semops -= 1;
> -			}
> +		pthread_mutex_lock(&conn_info->pending_semops_mutex);
> +
> +		assert(conn_info->pending_semops != 0);
> +
> +		while (conn_info->pending_semops > 0 &&
> +			((res = send (conn_info->fd, &buf, 1, MSG_NOSIGNAL)) == 1)) {
> +
> +			conn_info->pending_semops -= 1;
>  		}
> -		if (conn_info->poll_state == POLL_STATE_INOUT) {
> +
> +		if (conn_info->pending_semops == 0 && conn_info->poll_state == POLL_STATE_INOUT) {
>  			conn_info->poll_state = POLL_STATE_IN;
>  			api->poll_dispatch_modify (conn_info->fd, POLLIN|POLLNVAL);
>  		}
> +		pthread_mutex_unlock(&conn_info->pending_semops_mutex);
>  	}
>  
>  	return (0);
> 

_______________________________________________
discuss mailing list
discuss@xxxxxxxxxxxx
http://lists.corosync.org/mailman/listinfo/discuss


[Index of Archives]     [Linux Clusters]     [Corosync Project]     [Linux USB Devel]     [Linux Audio Users]     [Photo]     [Yosemite News]    [Yosemite Photos]    [Linux Kernel]     [Linux SCSI]     [X.Org]

  Powered by Linux