summaryrefslogtreecommitdiff
path: root/android/socket.c
diff options
context:
space:
mode:
authorAndrei Emeltchenko <andrei.emeltchenko@intel.com>2013-12-09 16:11:21 +0200
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2013-12-10 12:33:43 +0200
commitdff1938dac91f85ac912eac99e0d196d9bbdeff2 (patch)
tree929c9ef76c1854fe26bfcc322421ce3cf84536c9 /android/socket.c
parentdf71eaca9a4d9390854da1087b05b01ba5b7119e (diff)
downloadbluez-dff1938dac91f85ac912eac99e0d196d9bbdeff2.tar.gz
android/socket: Use getsockopt to set buffer
Use the RFCOMM socket buffer size to allocate the intermediate buffer used for copying data between sockets to minimize context switches.
Diffstat (limited to 'android/socket.c')
-rw-r--r--android/socket.c76
1 files changed, 58 insertions, 18 deletions
diff --git a/android/socket.c b/android/socket.c
index 90208740d..5e8f8e500 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -71,26 +71,37 @@ struct rfcomm_sock {
bdaddr_t dst;
uint32_t service_handle;
+ uint8_t *buf;
+ int buf_size;
+
const struct profile_info *profile;
};
-static struct rfcomm_sock *create_rfsock(int sock, int *hal_fd)
+static int rfsock_set_buffer(struct rfcomm_sock *rfsock)
{
- int fds[2] = {-1, -1};
- struct rfcomm_sock *rfsock;
+ socklen_t len = sizeof(int);
+ int rcv, snd, size, err;
- if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds) < 0) {
- error("socketpair(): %s", strerror(errno));
- *hal_fd = -1;
- return NULL;
+ err = getsockopt(rfsock->real_sock, SOL_SOCKET, SO_RCVBUF, &rcv, &len);
+ if (err < 0) {
+ error("getsockopt(SO_RCVBUF): %s", strerror(errno));
+ return -errno;
}
- rfsock = g_new0(struct rfcomm_sock, 1);
- rfsock->fd = fds[0];
- *hal_fd = fds[1];
- rfsock->real_sock = sock;
+ err = getsockopt(rfsock->real_sock, SOL_SOCKET, SO_SNDBUF, &snd, &len);
+ if (err < 0) {
+ error("getsockopt(SO_SNDBUF): %s", strerror(errno));
+ return -errno;
+ }
- return rfsock;
+ size = MAX(rcv, snd);
+
+ DBG("Set buffer size %d", size);
+
+ rfsock->buf = g_malloc(size);
+ rfsock->buf_size = size;
+
+ return 0;
}
static void cleanup_rfsock(gpointer data)
@@ -121,9 +132,39 @@ static void cleanup_rfsock(gpointer data)
if (rfsock->service_handle)
bt_adapter_remove_record(rfsock->service_handle);
+ if (rfsock->buf)
+ g_free(rfsock->buf);
+
g_free(rfsock);
}
+static struct rfcomm_sock *create_rfsock(int sock, int *hal_fd)
+{
+ int fds[2] = {-1, -1};
+ struct rfcomm_sock *rfsock;
+
+ if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds) < 0) {
+ error("socketpair(): %s", strerror(errno));
+ *hal_fd = -1;
+ return NULL;
+ }
+
+ rfsock = g_new0(struct rfcomm_sock, 1);
+ rfsock->fd = fds[0];
+ *hal_fd = fds[1];
+ rfsock->real_sock = sock;
+
+ if (sock < 0)
+ return rfsock;
+
+ if (rfsock_set_buffer(rfsock) < 0) {
+ cleanup_rfsock(rfsock);
+ return NULL;
+ }
+
+ return rfsock;
+}
+
static sdp_record_t *create_opp_record(uint8_t chan, const char *svc_name)
{
const char *service_name = "OBEX Object Push";
@@ -487,7 +528,6 @@ static gboolean sock_stack_event_cb(GIOChannel *io, GIOCondition cond,
gpointer data)
{
struct rfcomm_sock *rfsock = data;
- unsigned char buf[1024];
int len, sent;
if (cond & G_IO_HUP) {
@@ -501,14 +541,14 @@ static gboolean sock_stack_event_cb(GIOChannel *io, GIOCondition cond,
goto fail;
}
- len = read(rfsock->fd, buf, sizeof(buf));
+ len = read(rfsock->fd, rfsock->buf, rfsock->buf_size);
if (len <= 0) {
error("read(): %s", strerror(errno));
/* Read again */
return TRUE;
}
- sent = try_write_all(rfsock->real_sock, buf, len);
+ sent = try_write_all(rfsock->real_sock, rfsock->buf, len);
if (sent < 0) {
error("write(): %s", strerror(errno));
goto fail;
@@ -526,7 +566,6 @@ static gboolean sock_rfcomm_event_cb(GIOChannel *io, GIOCondition cond,
gpointer data)
{
struct rfcomm_sock *rfsock = data;
- unsigned char buf[1024];
int len, sent;
if (cond & G_IO_HUP) {
@@ -540,14 +579,14 @@ static gboolean sock_rfcomm_event_cb(GIOChannel *io, GIOCondition cond,
goto fail;
}
- len = read(rfsock->real_sock, buf, sizeof(buf));
+ len = read(rfsock->real_sock, rfsock->buf, rfsock->buf_size);
if (len <= 0) {
error("read(): %s", strerror(errno));
/* Read again */
return TRUE;
}
- sent = try_write_all(rfsock->fd, buf, len);
+ sent = try_write_all(rfsock->fd, rfsock->buf, len);
if (sent < 0) {
error("write(): %s", strerror(errno));
goto fail;
@@ -866,6 +905,7 @@ static void sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
}
rfsock->real_sock = g_io_channel_unix_get_fd(io);
+ rfsock_set_buffer(rfsock);
rfsock->channel = chan;
connections = g_list_append(connections, rfsock);