summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--proxy/src/client/gpm_common.c74
1 files changed, 30 insertions, 44 deletions
diff --git a/proxy/src/client/gpm_common.c b/proxy/src/client/gpm_common.c
index 8ac1a2a..df1f5a1 100644
--- a/proxy/src/client/gpm_common.c
+++ b/proxy/src/client/gpm_common.c
@@ -161,6 +161,7 @@ static int gpm_release_sock(struct gpm_ctx *gpmctx)
return pthread_mutex_unlock(&gpmctx->lock);
}
+/* must be called after the lock has been grabbed */
static int gpm_send_buffer(struct gpm_ctx *gpmctx,
char *buffer, uint32_t length)
{
@@ -174,8 +175,6 @@ static int gpm_send_buffer(struct gpm_ctx *gpmctx,
return EINVAL;
}
- gpm_grab_sock(gpmctx);
-
size = length | FRAGMENT_BIT;
size = htonl(size);
@@ -225,46 +224,29 @@ done:
/* on errors we can only close the fd and return */
gpm_close_socket(gpmctx);
}
- gpm_release_sock(gpmctx);
return ret;
}
+/* must be called after the lock has been grabbed */
static int gpm_recv_buffer(struct gpm_ctx *gpmctx,
char *buffer, uint32_t *length)
{
uint32_t size;
size_t rn;
size_t pos;
- bool retry;
int ret;
- gpm_grab_sock(gpmctx);
-
- retry = false;
+ ret = 0;
do {
- ret = 0;
- do {
- rn = read(gpmctx->fd, &size, sizeof(uint32_t));
- if (rn == -1) {
- ret = errno;
- }
- } while (ret == EINTR);
- if (rn != 4) {
- /* reopen and retry once */
- if (retry == false) {
- gpm_close_socket(gpmctx);
- ret = gpm_open_socket(gpmctx);
- if (ret == 0) {
- retry = true;
- continue;
- }
- } else {
- ret = EIO;
- }
- goto done;
+ rn = read(gpmctx->fd, &size, sizeof(uint32_t));
+ if (rn == -1) {
+ ret = errno;
}
- retry = false;
- } while (retry);
+ } while (ret == EINTR);
+ if (rn != 4) {
+ ret = EIO;
+ goto done;
+ }
*length = ntohl(size);
*length &= ~FRAGMENT_BIT;
@@ -298,29 +280,22 @@ done:
/* on errors we can only close the fd and return */
gpm_close_socket(gpmctx);
}
- gpm_release_sock(gpmctx);
return ret;
}
-static int gpm_next_xid(struct gpm_ctx *gpmctx, uint32_t *xid)
+/* must be called after the lock has been grabbed */
+static uint32_t gpm_next_xid(struct gpm_ctx *gpmctx)
{
- int ret;
-
- ret = gpm_grab_sock(gpmctx);
- if (ret) {
- goto done;
- }
+ uint32_t xid;
if (gpmctx->next_xid < 0) {
- *xid = 0;
gpmctx->next_xid = 1;
+ xid = 0;
} else {
- *xid = gpmctx->next_xid++;
+ xid = gpmctx->next_xid++;
}
-done:
- gpm_release_sock(gpmctx);
- return ret;
+ return xid;
}
static struct gpm_ctx *gpm_get_ctx(void)
@@ -435,6 +410,7 @@ int gpm_make_call(int proc, union gp_rpc_arg *arg, union gp_rpc_res *res)
uint32_t length;
uint32_t xid;
bool xdrok;
+ bool sockgrab = false;
int ret;
xdrmem_create(&xdr_call_ctx, buffer, MAX_RPC_SIZE, XDR_ENCODE);
@@ -458,11 +434,14 @@ int gpm_make_call(int proc, union gp_rpc_arg *arg, union gp_rpc_res *res)
return EINVAL;
}
- ret = gpm_next_xid(gpmctx, &xid);
+ /* grab the lock for the whole conversation */
+ ret = gpm_grab_sock(gpmctx);
if (ret) {
goto done;
}
- msg.xid = xid;
+ sockgrab = true;
+
+ msg.xid = xid = gpm_next_xid(gpmctx);
/* encode header */
xdrok = xdr_gp_rpc_msg(&xdr_call_ctx, &msg);
@@ -490,6 +469,10 @@ int gpm_make_call(int proc, union gp_rpc_arg *arg, union gp_rpc_res *res)
goto done;
}
+ /* release the lock */
+ gpm_release_sock(gpmctx);
+ sockgrab = false;
+
/* decode header */
xdrok = xdr_gp_rpc_msg(&xdr_reply_ctx, &msg);
if (!xdrok) {
@@ -512,6 +495,9 @@ int gpm_make_call(int proc, union gp_rpc_arg *arg, union gp_rpc_res *res)
}
done:
+ if (sockgrab) {
+ gpm_release_sock(gpmctx);
+ }
xdr_free((xdrproc_t)xdr_gp_rpc_msg, (char *)&msg);
xdr_destroy(&xdr_call_ctx);
xdr_destroy(&xdr_reply_ctx);