*/
#include "udebug-priv.h"
-static struct udebug_client_msg *
-send_and_wait(struct udebug *ctx, struct udebug_client_msg *msg, int *rfd)
-{
- int type = msg->type;
- int fd = -1;
-
- udebug_send_msg(ctx, msg, NULL, -1);
-
- do {
- if (fd >= 0)
- close(fd);
- fd = -1;
- msg = __udebug_poll(ctx, &fd, true);
- } while (msg && msg->type != type);
- if (!msg)
- return NULL;
-
- if (rfd)
- *rfd = fd;
- else if (fd >= 0)
- close(fd);
-
- return msg;
-}
-
static int
udebug_remote_get_handle(struct udebug *ctx)
{
if (ctx->poll_handle >= 0 || !udebug_is_connected(ctx))
return 0;
- msg = send_and_wait(ctx, &send_msg, NULL);
+ msg = udebug_send_and_wait(ctx, &send_msg, NULL);
if (!msg)
return -1;
if (rb->buf.data || !udebug_is_connected(ctx))
return -1;
- msg = send_and_wait(ctx, &send_msg, &fd);
+ msg = udebug_send_and_wait(ctx, &send_msg, &fd);
if (!msg || fd < 0)
return -1;
return total;
}
-void udebug_send_msg(struct udebug *ctx, struct udebug_client_msg *msg,
- struct blob_attr *meta, int fd)
+static void
+udebug_send_msg(struct udebug *ctx, struct udebug_client_msg *msg,
+ struct blob_attr *meta, int fd)
{
struct iovec iov[2] = {
{ .iov_base = msg, .iov_len = sizeof(*msg) },
writev_retry(ctx->fd.fd, iov, ARRAY_SIZE(iov), fd);
}
+static bool
+udebug_recv_msg(struct udebug *ctx, struct udebug_client_msg *msg, int *fd,
+ bool wait)
+{
+ struct iovec iov = {
+ .iov_base = msg,
+ .iov_len = sizeof(*msg)
+ };
+ int ret;
+
+ ret = recv_retry(ctx->fd.fd, &iov, wait, fd);
+ if (ret == -2)
+ __udebug_disconnect(ctx, true);
+
+ return ret == sizeof(*msg);
+}
+
+static struct udebug_client_msg *
+__udebug_poll(struct udebug *ctx, int *fd, bool wait)
+{
+ static struct udebug_client_msg msg = {};
+
+ while (udebug_recv_msg(ctx, &msg, fd, wait)) {
+ struct udebug_remote_buf *rb;
+ void *key;
+
+ if (msg.type != CL_MSG_RING_NOTIFY)
+ return &msg;
+
+ if (fd && *fd >= 0)
+ close(*fd);
+
+ if (!ctx->notify_cb)
+ continue;
+
+ key = (void *)(uintptr_t)msg.id;
+ rb = avl_find_element(&ctx->remote_rings, key, rb, node);
+ if (!rb || !rb->poll)
+ continue;
+
+ if (ctx->poll_handle >= 0)
+ __atomic_fetch_or(&rb->buf.hdr->notify,
+ 1UL << ctx->poll_handle,
+ __ATOMIC_RELAXED);
+ ctx->notify_cb(ctx, rb);
+ }
+
+ return NULL;
+}
+
+static struct udebug_client_msg *
+udebug_wait_for_response(struct udebug *ctx, struct udebug_client_msg *msg, int *rfd)
+{
+ int type = msg->type;
+ int fd = -1;
+
+ do {
+ if (fd >= 0)
+ close(fd);
+ fd = -1;
+ msg = __udebug_poll(ctx, &fd, true);
+ } while (msg && msg->type != type);
+ if (!msg)
+ return NULL;
+
+ if (rfd)
+ *rfd = fd;
+ else if (fd >= 0)
+ close(fd);
+
+ return msg;
+}
+
static void
udebug_buf_msg(struct udebug_buf *buf, enum udebug_client_msg_type type)
{
};
udebug_send_msg(buf->ctx, &msg, NULL, -1);
+ udebug_wait_for_response(buf->ctx, &msg, NULL);
}
static size_t __udebug_headsize(unsigned int ring_size, unsigned int page_size)
blobmsg_close_array(&b, c);
udebug_send_msg(ctx, &msg, b.head, buf->fd);
+ udebug_wait_for_response(ctx, &msg, NULL);
}
int udebug_buf_add(struct udebug *ctx, struct udebug_buf *buf,
return 0;
}
-static bool
-udebug_recv_msg(struct udebug *ctx, struct udebug_client_msg *msg, int *fd,
- bool wait)
+void udebug_poll(struct udebug *ctx)
{
- struct iovec iov = {
- .iov_base = msg,
- .iov_len = sizeof(*msg)
- };
- int ret;
-
- ret = recv_retry(ctx->fd.fd, &iov, wait, fd);
- if (ret == -2)
- __udebug_disconnect(ctx, true);
-
- return ret == sizeof(*msg);
+ while (__udebug_poll(ctx, NULL, false));
}
-struct udebug_client_msg *__udebug_poll(struct udebug *ctx, int *fd, bool wait)
+struct udebug_client_msg *
+udebug_send_and_wait(struct udebug *ctx, struct udebug_client_msg *msg, int *rfd)
{
- static struct udebug_client_msg msg = {};
-
- while (udebug_recv_msg(ctx, &msg, fd, wait)) {
- struct udebug_remote_buf *rb;
- void *key;
-
- if (msg.type != CL_MSG_RING_NOTIFY)
- return &msg;
-
- if (fd && *fd >= 0)
- close(*fd);
-
- if (!ctx->notify_cb)
- continue;
-
- key = (void *)(uintptr_t)msg.id;
- rb = avl_find_element(&ctx->remote_rings, key, rb, node);
- if (!rb || !rb->poll)
- continue;
+ udebug_send_msg(ctx, msg, NULL, -1);
- if (ctx->poll_handle >= 0)
- __atomic_fetch_or(&rb->buf.hdr->notify,
- 1UL << ctx->poll_handle,
- __ATOMIC_RELAXED);
- ctx->notify_cb(ctx, rb);
- }
-
- return NULL;
-}
-
-void udebug_poll(struct udebug *ctx)
-{
- while (__udebug_poll(ctx, NULL, false));
+ return udebug_wait_for_response(ctx, msg, rfd);
}
static void udebug_fd_cb(struct uloop_fd *fd, unsigned int events)