socket.cc revision d6121a37c579731b89348e618a823c53b938449a
1c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville/******************************************************************************
2c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *
3c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *  Copyright (C) 2014 Google, Inc.
4c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *
5c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *  Licensed under the Apache License, Version 2.0 (the "License");
6c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *  you may not use this file except in compliance with the License.
7c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *  You may obtain a copy of the License at:
8c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *
9c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *  http://www.apache.org/licenses/LICENSE-2.0
10c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *
11c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *  Unless required by applicable law or agreed to in writing, software
12c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *  distributed under the License is distributed on an "AS IS" BASIS,
13c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *  See the License for the specific language governing permissions and
15c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *  limitations under the License.
16c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville *
174918296afe1c667e9523cdfc799f558f7ebc2bfbWink Saville ******************************************************************************/
18c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
19cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla#define LOG_TAG "bt_osi_socket"
20c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
212b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen#include "osi/include/socket.h"
22c9b81a0c05128694c617fcdd67e73821895822feWink Saville
23b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen#include <asm/ioctls.h>
24c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville#include <assert.h>
25cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville#include <errno.h>
26c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville#include <netinet/in.h>
27c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville#include <string.h>
28c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville#include <sys/ioctl.h>
291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu#include <sys/socket.h>
30cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville#include <unistd.h>
31c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
32cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville#include "osi/include/allocator.h"
33cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville#include "osi/include/log.h"
34c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville#include "osi/include/osi.h"
3596cce86cf08e37e0f09ed5057b1196e26b302743Robert Greenwalt#include "osi/include/reactor.h"
36cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu// The IPv4 loopback address: 127.0.0.1
38af5593594070f825032be46dced573cd195956e1Robert Greenwaltstatic const in_addr_t LOCALHOST_ = 0x7f000001;
39cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
409c180aedfc9f0d20525c0128487d3500e6c0a715Jason Monkstruct socket_t {
411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu  int fd;
42cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville  reactor_object_t *reactor_object;
431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu  socket_cb read_ready;
44c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville  socket_cb write_ready;
453fad7daba62dcb7aafc4adc7f8cc123726ed5a7cRobert Greenwalt  void *context;                     // Not owned, do not free.
46b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen};
47a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yustatic void internal_read_ready(void *context);
49c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savillestatic void internal_write_ready(void *context);
5047588e2307efe45b21bf8384cf5fc49d167e2452Jordan Liu
51a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savillesocket_t *socket_new(void) {
52b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen  socket_t *ret = (socket_t *)osi_calloc(sizeof(socket_t));
53c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
54c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville  ret->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu  if (ret->fd == INVALID_FD) {
56c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville    LOG_ERROR(LOG_TAG, "%s unable to create socket: %s", __func__, strerror(errno));
571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    goto error;
58cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville  }
5947588e2307efe45b21bf8384cf5fc49d167e2452Jordan Liu
60cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville  int enable = 1;
612e2ec7d6844b8441df95b9ff38129e1e4a2d18f3Robert Greenwalt  if (setsockopt(ret->fd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable)) == -1) {
624c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu    LOG_ERROR(LOG_TAG, "%s unable to set SO_REUSEADDR: %s", __func__, strerror(errno));
630e776303ca82b5bec5db19bb44e0f13b0c7c6400Etan Cohen    goto error;
64a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville  }
651a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
664c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu  return ret;
67cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
68cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Savilleerror:;
69c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville  if (ret)
70cebb2cc576c652dd642d7f419532ec04e0f59d7dNaveen Kalla    close(ret->fd);
712dde8b1659b1eb231e667bc19307ef294b627bebRobert Greenwalt  osi_free(ret);
72ea763d93b231bccf7e476b625fa028bef7874bf8Robert Greenwalt  return NULL;
73af5593594070f825032be46dced573cd195956e1Robert Greenwalt}
742b7b6016c7a5f2c3ce9c7e623ea10a9fe9239dc2Paul Jensen
75c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savillesocket_t *socket_new_from_fd(int fd) {
761a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu  assert(fd != INVALID_FD);
77af5593594070f825032be46dced573cd195956e1Robert Greenwalt
78b5771d36210a751e6ec916556ad0f20fcb9b4288fionaxu  socket_t *ret = (socket_t *)osi_calloc(sizeof(socket_t));
79cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville
80cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville  ret->fd = fd;
814c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu  return ret;
82b449dc75ef4b9cb996c34a11e758f7e6ca193240Paul Jensen}
834c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu
844918296afe1c667e9523cdfc799f558f7ebc2bfbWink Savillevoid socket_free(socket_t *socket) {
85cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville  if (!socket)
864c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu    return;
87a02b6fd88953d783c32e6d7f84b7eddbc0d1faf1fionaxu
88f2d0fa64860a12423fb8709766d6af90fba5e6cfJack Yu  socket_unregister(socket);
89d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenka  close(socket->fd);
90bb36adde615d3d85fa0fc23935197c6bc6a799edAlex Yakavenka  osi_free(socket);
9176f43316a5a6082d601bffd4b6898d0bd81e11fcram}
924c31e4c0d2db31fe84081aa6f1e2bcc08b31f9d3fionaxu
93c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Savillebool socket_listen(const socket_t *socket, port_t port) {
94c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville  assert(socket != NULL);
95c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
96c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville  struct sockaddr_in addr;
9729c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt  addr.sin_family = AF_INET;
981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu  addr.sin_addr.s_addr = htonl(LOCALHOST_);
991a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu  addr.sin_port = htons(port);
10068f4f4a0bc8d4060b5775e7a24a97ea5b485989efionaxu  if (bind(socket->fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
1011a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    LOG_ERROR(LOG_TAG, "%s unable to bind socket to port %u: %s", __func__, port, strerror(errno));
1021a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    return false;
10329c6659c8767212d23d417f2b7f032b6c0d82119Robert Greenwalt  }
1041a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1051a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu  if (listen(socket->fd, 10) == -1) {
1061a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    LOG_ERROR(LOG_TAG, "%s unable to listen on port %u: %s", __func__, port, strerror(errno));
1071a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    return false;
1081a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu  }
1091a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
110c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville  return true;
111c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville}
112c38bb60d867c5d61d90b7179a9ed2b2d1848124fWink Saville
1130c3ec24396bb8c21b4d89f743b626c13dd35ba7bAmit Mahajansocket_t *socket_accept(const socket_t *socket) {
1141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu  assert(socket != NULL);
1151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu  int fd;
1171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu  OSI_NO_INTR(fd = accept(socket->fd, NULL, NULL));
1181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu  if (fd == INVALID_FD) {
1191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    LOG_ERROR(LOG_TAG, "%s unable to accept socket: %s", __func__, strerror(errno));
1200e664d8c9ff3a1f2ab03d2bef4268615335ea1a2Jack Yu    return NULL;
1211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu  }
1221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu  socket_t *ret = (socket_t *)osi_calloc(sizeof(socket_t));
1241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu  ret->fd = fd;
1261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu  return ret;
127a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu}
128a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yu
129a8f5a859f8e4a15902d729af5d2edc9a9433ba41Jack Yussize_t socket_read(const socket_t *socket, void *buf, size_t count) {
1300a39f581e11eb7b040a5412229164ef72044279fRobert Greenwalt  assert(socket != NULL);
1311a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu  assert(buf != NULL);
1321a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1331a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu  ssize_t ret;
1341a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu  OSI_NO_INTR(ret = recv(socket->fd, buf, count, MSG_DONTWAIT));
1351a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1361a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu  return ret;
1371a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu}
1381a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1391a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yussize_t socket_write(const socket_t *socket, const void *buf, size_t count) {
1401a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu  assert(socket != NULL);
1411a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu  assert(buf != NULL);
1421a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1431a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu  ssize_t ret;
1441a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu  OSI_NO_INTR(ret = send(socket->fd, buf, count, MSG_DONTWAIT));
1451a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1461a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu  return ret;
1471a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu}
1481a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1491a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yussize_t socket_write_and_transfer_fd(const socket_t *socket, const void *buf, size_t count, int fd) {
1501a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu  assert(socket != NULL);
1511a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu  assert(buf != NULL);
1521a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1531a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu  if (fd == INVALID_FD)
1541a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu    return socket_write(socket, buf, count);
1551a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1561a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu  struct msghdr msg;
1571a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu  struct iovec iov;
1581a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu  char control_buf[CMSG_SPACE(sizeof(int))];
1591a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1601a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu  iov.iov_base = (void *)buf;
1611a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu  iov.iov_len = count;
1621a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
1633d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu  msg.msg_iov = &iov;
1643d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu  msg.msg_iovlen = 1;
1653d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu  msg.msg_control = control_buf;
1663d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu  msg.msg_controllen = sizeof(control_buf);
1673d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu  msg.msg_name = NULL;
1683d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu  msg.msg_namelen = 0;
1693d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
1703d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu  struct cmsghdr *header = CMSG_FIRSTHDR(&msg);
1713d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu  header->cmsg_level = SOL_SOCKET;
1723d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu  header->cmsg_type = SCM_RIGHTS;
1733d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu  header->cmsg_len = CMSG_LEN(sizeof(int));
1743d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu  *(int *)CMSG_DATA(header) = fd;
1753d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
1763d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu  ssize_t ret;
1773d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu  OSI_NO_INTR(ret = sendmsg(socket->fd, &msg, MSG_DONTWAIT));
1783d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
1793d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu  close(fd);
1803d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu  return ret;
1813d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu}
1823d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
1833d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxussize_t socket_bytes_available(const socket_t *socket) {
1843d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu  assert(socket != NULL);
1853d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
1863d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu  int size = 0;
1873d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu  if (ioctl(socket->fd, FIONREAD, &size) == -1)
1883d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu    return -1;
1893d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu  return size;
1903d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu}
1913d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
1923d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxuvoid socket_register(socket_t *socket, reactor_t *reactor, void *context, socket_cb read_cb, socket_cb write_cb) {
1933d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu  assert(socket != NULL);
1943d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
1953d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu  // Make sure the socket isn't currently registered.
1963d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu  socket_unregister(socket);
1973d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
1983d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu  socket->read_ready = read_cb;
1993d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu  socket->write_ready = write_cb;
2003d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu  socket->context = context;
2013d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
2023d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu  void (*read_fn)(void *) = (read_cb != NULL) ? internal_read_ready : NULL;
2033d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu  void (*write_fn)(void *) = (write_cb != NULL) ? internal_write_ready : NULL;
2040d5e6cc0fdfb839d63abe1e7eb85eee1b5942108fionaxu
2050d5e6cc0fdfb839d63abe1e7eb85eee1b5942108fionaxu  socket->reactor_object = reactor_register(reactor, socket->fd, socket, read_fn, write_fn);
2063d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu}
2073d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
2083d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxuvoid socket_unregister(socket_t *socket) {
2093d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu  assert(socket != NULL);
2103d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu
2113d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu  if (socket->reactor_object)
2123d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu    reactor_unregister(socket->reactor_object);
2133d8c0f70a6fa7a53fda3c5d592de0ac3aa247e3cfionaxu  socket->reactor_object = NULL;
2141a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu}
2151a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2161a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yustatic void internal_read_ready(void *context) {
2171a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu  assert(context != NULL);
2181a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2191a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu  socket_t *socket = (void *)context;
2201a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu  socket->read_ready(socket, socket->context);
2211a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu}
2221a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2231a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yustatic void internal_write_ready(void *context) {
2241a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu  assert(context != NULL);
2251a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu
2261a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu  socket_t *socket = (void *)context;
2271a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu  socket->write_ready(socket, socket->context);
2281a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu}
2291a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu