aboutsummaryrefslogtreecommitdiff
path: root/src/util/service_new.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/service_new.c')
-rw-r--r--src/util/service_new.c102
1 files changed, 94 insertions, 8 deletions
diff --git a/src/util/service_new.c b/src/util/service_new.c
index d6eda3250..fe8e79f17 100644
--- a/src/util/service_new.c
+++ b/src/util/service_new.c
@@ -266,6 +266,11 @@ struct GNUNET_SERVICE_Client
266 struct GNUNET_SCHEDULER_Task *send_task; 266 struct GNUNET_SCHEDULER_Task *send_task;
267 267
268 /** 268 /**
269 * Pointer to the message to be transmitted by @e send_task.
270 */
271 const struct GNUNET_MessageHeader *msg;
272
273 /**
269 * User context value, value returned from 274 * User context value, value returned from
270 * the connect callback. 275 * the connect callback.
271 */ 276 */
@@ -276,6 +281,11 @@ struct GNUNET_SERVICE_Client
276 * to the application. 281 * to the application.
277 */ 282 */
278 struct GNUNET_TIME_Absolute warn_start; 283 struct GNUNET_TIME_Absolute warn_start;
284
285 /**
286 * Current position in @e msg at which we are transmitting.
287 */
288 size_t msg_pos;
279 289
280 /** 290 /**
281 * Persist the file handle for this client no matter what happens, 291 * Persist the file handle for this client no matter what happens,
@@ -1776,24 +1786,86 @@ GNUNET_SERVICE_suspend (struct GNUNET_SERVICE_Handle *sh)
1776 1786
1777 1787
1778/** 1788/**
1789 * Task run when we are ready to transmit data to the
1790 * client.
1791 *
1792 * @param cls the `struct GNUNET_SERVICE_Client *` to send to
1793 */
1794static void
1795do_send (void *cls)
1796{
1797 struct GNUNET_SERVICE_Client *client = cls;
1798 ssize_t ret;
1799 size_t left;
1800 const char *buf;
1801
1802 client->send_task = NULL;
1803 buf = (const char *) client->msg;
1804 left = ntohs (client->msg->size) - client->msg_pos;
1805 ret = GNUNET_NETWORK_socket_send (client->sock,
1806 &buf[client->msg_pos],
1807 left);
1808 GNUNET_assert (ret <= (ssize_t) left);
1809 if (0 == ret)
1810 {
1811 GNUNET_MQ_inject_error (client->mq,
1812 GNUNET_MQ_ERROR_WRITE);
1813 return;
1814 }
1815 if (-1 == ret)
1816 {
1817 if ( (EAGAIN == errno) ||
1818 (EINTR == errno) )
1819 {
1820 /* ignore */
1821 ret = 0;
1822 }
1823 else
1824 {
1825 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
1826 "send");
1827 GNUNET_MQ_inject_error (client->mq,
1828 GNUNET_MQ_ERROR_WRITE);
1829 return;
1830 }
1831 }
1832 client->msg_pos += ret;
1833 if (left > ret)
1834 {
1835 client->send_task
1836 = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
1837 client->sock,
1838 &do_send,
1839 client);
1840 return;
1841 }
1842 GNUNET_MQ_impl_send_continue (client->mq);
1843}
1844
1845
1846/**
1779 * Signature of functions implementing the sending functionality of a 1847 * Signature of functions implementing the sending functionality of a
1780 * message queue. 1848 * message queue.
1781 * 1849 *
1782 * @param mq the message queue 1850 * @param mq the message queue
1783 * @param msg the message to send 1851 * @param msg the message to send
1784 * @param impl_state state of the implementation 1852 * @param impl_state our `struct GNUNET_SERVICE_Client *`
1785 */ 1853 */
1786static void 1854static void
1787service_mq_send (struct GNUNET_MQ_Handle *mq, 1855service_mq_send (struct GNUNET_MQ_Handle *mq,
1788 const struct GNUNET_MessageHeader *msg, 1856 const struct GNUNET_MessageHeader *msg,
1789 void *impl_state) 1857 void *impl_state)
1790{ 1858{
1791 // struct GNUNET_SERVICE_Client *client = cls; 1859 struct GNUNET_SERVICE_Client *client = impl_state;
1792 1860
1793 // FIXME 1: setup "client->send_task" for transmission. 1861 GNUNET_assert (NULL == client->send_task);
1794 // FIXME 2: I seriously hope we do not need to make a copy of `msg`! 1862 client->msg = msg;
1795 // OPTIMIZATION: ideally, we'd like the ability to peak at the rest of 1863 client->msg_pos = 0;
1796 // the queue and transmit more than one message if possible. 1864 client->send_task
1865 = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
1866 client->sock,
1867 &do_send,
1868 client);
1797} 1869}
1798 1870
1799 1871
@@ -1807,8 +1879,9 @@ static void
1807service_mq_cancel (struct GNUNET_MQ_Handle *mq, 1879service_mq_cancel (struct GNUNET_MQ_Handle *mq,
1808 void *impl_state) 1880 void *impl_state)
1809{ 1881{
1810 // struct GNUNET_SERVICE_Client *client = cls; 1882 struct GNUNET_SERVICE_Client *client = impl_state;
1811 1883
1884 GNUNET_assert (0); // not implemented
1812 // FIXME: stop transmission! (must be possible, otherwise 1885 // FIXME: stop transmission! (must be possible, otherwise
1813 // we must have told MQ that the message was sent!) 1886 // we must have told MQ that the message was sent!)
1814} 1887}
@@ -2334,4 +2407,17 @@ GNUNET_SERVICE_client_persist (struct GNUNET_SERVICE_Client *c)
2334} 2407}
2335 2408
2336 2409
2410/**
2411 * Obtain the message queue of @a c. Convenience function.
2412 *
2413 * @param c the client to continue receiving from
2414 * @return the message queue of @a c
2415 */
2416struct GNUNET_MQ_Handle *
2417GNUNET_SERVICE_client_get_mq (struct GNUNET_SERVICE_Client *c)
2418{
2419 return c->mq;
2420}
2421
2422
2337/* end of service_new.c */ 2423/* end of service_new.c */