diff options
Diffstat (limited to 'src/util/service_new.c')
-rw-r--r-- | src/util/service_new.c | 102 |
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 | */ | ||
1794 | static void | ||
1795 | do_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 | */ |
1786 | static void | 1854 | static void |
1787 | service_mq_send (struct GNUNET_MQ_Handle *mq, | 1855 | service_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 | |||
1807 | service_mq_cancel (struct GNUNET_MQ_Handle *mq, | 1879 | service_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 | */ | ||
2416 | struct GNUNET_MQ_Handle * | ||
2417 | GNUNET_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 */ |