aboutsummaryrefslogtreecommitdiff
path: root/src/transport/transport_api.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2015-10-07 08:24:43 +0000
committerChristian Grothoff <christian@grothoff.org>2015-10-07 08:24:43 +0000
commit503c615cff298a83a09751bb57dc7da5251ff742 (patch)
treebbcef110a129e46582ec48069f8612bc3fc32806 /src/transport/transport_api.c
parentc48e2c3c602bc360b6278b50fe960ad66cb212e1 (diff)
downloadgnunet-503c615cff298a83a09751bb57dc7da5251ff742.tar.gz
gnunet-503c615cff298a83a09751bb57dc7da5251ff742.zip
-adding more logging to diagnose transport transmission delays
Diffstat (limited to 'src/transport/transport_api.c')
-rw-r--r--src/transport/transport_api.c182
1 files changed, 151 insertions, 31 deletions
diff --git a/src/transport/transport_api.c b/src/transport/transport_api.c
index 312762ba4..9d221c69e 100644
--- a/src/transport/transport_api.c
+++ b/src/transport/transport_api.c
@@ -38,6 +38,12 @@
38#define LOG(kind,...) GNUNET_log_from (kind, "transport-api",__VA_ARGS__) 38#define LOG(kind,...) GNUNET_log_from (kind, "transport-api",__VA_ARGS__)
39 39
40/** 40/**
41 * If we could not send any payload to a peer for this amount of
42 * time, we print a warning.
43 */
44#define UNREADY_WARN_TIME GNUNET_TIME_UNIT_MINUTES
45
46/**
41 * How large to start with for the hashmap of neighbours. 47 * How large to start with for the hashmap of neighbours.
42 */ 48 */
43#define STARTING_NEIGHBOURS_SIZE 16 49#define STARTING_NEIGHBOURS_SIZE 16
@@ -76,6 +82,11 @@ struct GNUNET_TRANSPORT_TransmitHandle
76 void *notify_cls; 82 void *notify_cls;
77 83
78 /** 84 /**
85 * Time at which this request was originally scheduled.
86 */
87 struct GNUNET_TIME_Absolute request_start;
88
89 /**
79 * Timeout for this request, 0 for control messages. 90 * Timeout for this request, 0 for control messages.
80 */ 91 */
81 struct GNUNET_TIME_Absolute timeout; 92 struct GNUNET_TIME_Absolute timeout;
@@ -130,6 +141,16 @@ struct Neighbour
130 struct GNUNET_CONTAINER_HeapNode *hn; 141 struct GNUNET_CONTAINER_HeapNode *hn;
131 142
132 /** 143 /**
144 * Last time when this peer received payload from us.
145 */
146 struct GNUNET_TIME_Absolute last_payload;
147
148 /**
149 * Task to trigger warnings if we do not get SEND_OK after a while.
150 */
151 struct GNUNET_SCHEDULER_Task *unready_warn_task;
152
153 /**
133 * Is this peer currently ready to receive a message? 154 * Is this peer currently ready to receive a message?
134 */ 155 */
135 int is_ready; 156 int is_ready;
@@ -434,7 +455,7 @@ struct GNUNET_TRANSPORT_Handle
434 /** 455 /**
435 * ID of the task trying to reconnect to the service. 456 * ID of the task trying to reconnect to the service.
436 */ 457 */
437 struct GNUNET_SCHEDULER_Task * reconnect_task; 458 struct GNUNET_SCHEDULER_Task *reconnect_task;
438 459
439 /** 460 /**
440 * ID of the task trying to trigger transmission for a peer while 461 * ID of the task trying to trigger transmission for a peer while
@@ -483,6 +504,32 @@ disconnect_and_schedule_reconnect (struct GNUNET_TRANSPORT_Handle *h);
483 504
484 505
485/** 506/**
507 * A neighbour has not gotten a SEND_OK in a while. Print a warning.
508 *
509 * @param cls the `struct Neighbour`
510 * @param tc scheduler context
511 */
512static void
513do_warn_unready (void *cls,
514 const struct GNUNET_SCHEDULER_TaskContext *tc)
515{
516 struct Neighbour *n = cls;
517 struct GNUNET_TIME_Relative delay;
518
519 delay = GNUNET_TIME_absolute_get_duration (n->last_payload);
520 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
521 "Lacking SEND_OK, no payload could be send to %s for %s\n",
522 GNUNET_i2s (&n->id),
523 GNUNET_STRINGS_relative_time_to_string (delay,
524 GNUNET_YES));
525 n->unready_warn_task
526 = GNUNET_SCHEDULER_add_delayed (UNREADY_WARN_TIME,
527 &do_warn_unready,
528 n);
529}
530
531
532/**
486 * Get the neighbour list entry for the given peer 533 * Get the neighbour list entry for the given peer
487 * 534 *
488 * @param h our context 535 * @param h our context
@@ -595,10 +642,18 @@ neighbour_delete (void *cls,
595 struct GNUNET_TRANSPORT_Handle *handle = cls; 642 struct GNUNET_TRANSPORT_Handle *handle = cls;
596 struct Neighbour *n = value; 643 struct Neighbour *n = value;
597 644
645 LOG (GNUNET_ERROR_TYPE_DEBUG,
646 "Dropping entry for neighbour `%s'.\n",
647 GNUNET_i2s (key));
598 GNUNET_BANDWIDTH_tracker_notification_stop (&n->out_tracker); 648 GNUNET_BANDWIDTH_tracker_notification_stop (&n->out_tracker);
599 if (NULL != handle->nd_cb) 649 if (NULL != handle->nd_cb)
600 handle->nd_cb (handle->cls, 650 handle->nd_cb (handle->cls,
601 &n->id); 651 &n->id);
652 if (NULL != n->unready_warn_task)
653 {
654 GNUNET_SCHEDULER_cancel (n->unready_warn_task);
655 n->unready_warn_task = NULL;
656 }
602 GNUNET_assert (NULL == n->th); 657 GNUNET_assert (NULL == n->th);
603 GNUNET_assert (NULL == n->hn); 658 GNUNET_assert (NULL == n->hn);
604 GNUNET_assert (GNUNET_YES == 659 GNUNET_assert (GNUNET_YES ==
@@ -752,10 +807,15 @@ demultiplexer (void *cls,
752 "Receiving SEND_OK message, transmission %s.\n", 807 "Receiving SEND_OK message, transmission %s.\n",
753 ntohl (okm->success) == GNUNET_OK ? "succeeded" : "failed"); 808 ntohl (okm->success) == GNUNET_OK ? "succeeded" : "failed");
754 809
755 n = neighbour_find (h, &okm->peer); 810 n = neighbour_find (h,
811 &okm->peer);
756 if (NULL == n) 812 if (NULL == n)
813 {
814 /* we should never get a 'SEND_OK' for a peer that we are not
815 connected to */
816 GNUNET_break (0);
757 break; 817 break;
758 818 }
759 if (bytes_physical >= bytes_msg) 819 if (bytes_physical >= bytes_msg)
760 { 820 {
761 LOG (GNUNET_ERROR_TYPE_DEBUG, 821 LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -766,6 +826,8 @@ demultiplexer (void *cls,
766 } 826 }
767 GNUNET_break (GNUNET_NO == n->is_ready); 827 GNUNET_break (GNUNET_NO == n->is_ready);
768 n->is_ready = GNUNET_YES; 828 n->is_ready = GNUNET_YES;
829 GNUNET_SCHEDULER_cancel (n->unready_warn_task);
830 n->unready_warn_task = NULL;
769 if ((NULL != n->th) && (NULL == n->hn)) 831 if ((NULL != n->th) && (NULL == n->hn))
770 { 832 {
771 GNUNET_assert (NULL != n->th->timeout_task); 833 GNUNET_assert (NULL != n->th->timeout_task);
@@ -847,8 +909,15 @@ timeout_request_due_to_congestion (void *cls,
847{ 909{
848 struct GNUNET_TRANSPORT_TransmitHandle *th = cls; 910 struct GNUNET_TRANSPORT_TransmitHandle *th = cls;
849 struct Neighbour *n = th->neighbour; 911 struct Neighbour *n = th->neighbour;
912 struct GNUNET_TIME_Relative delay;
850 913
851 n->th->timeout_task = NULL; 914 n->th->timeout_task = NULL;
915 delay = GNUNET_TIME_absolute_get_duration (th->request_start);
916 LOG (GNUNET_ERROR_TYPE_WARNING,
917 "Discarding %u bytes of payload message after %s delay due to congestion\n",
918 th->notify_size,
919 GNUNET_STRINGS_relative_time_to_string (delay,
920 GNUNET_YES));
852 GNUNET_assert (th == n->th); 921 GNUNET_assert (th == n->th);
853 GNUNET_assert (NULL == n->hn); 922 GNUNET_assert (NULL == n->hn);
854 n->th = NULL; 923 n->th = NULL;
@@ -874,6 +943,7 @@ transport_notify_ready (void *cls,
874{ 943{
875 struct GNUNET_TRANSPORT_Handle *h = cls; 944 struct GNUNET_TRANSPORT_Handle *h = cls;
876 struct GNUNET_TRANSPORT_TransmitHandle *th; 945 struct GNUNET_TRANSPORT_TransmitHandle *th;
946 struct GNUNET_TIME_Relative delay;
877 struct Neighbour *n; 947 struct Neighbour *n;
878 char *cbuf; 948 char *cbuf;
879 struct OutboundMessage obm; 949 struct OutboundMessage obm;
@@ -899,19 +969,32 @@ transport_notify_ready (void *cls,
899 GNUNET_CONTAINER_DLL_remove (h->control_head, 969 GNUNET_CONTAINER_DLL_remove (h->control_head,
900 h->control_tail, 970 h->control_tail,
901 th); 971 th);
902 nret = th->notify (th->notify_cls, size, &cbuf[ret]); 972 nret = th->notify (th->notify_cls,
903 LOG (GNUNET_ERROR_TYPE_DEBUG, 973 size,
904 "Added %u bytes of control message at %u\n", 974 &cbuf[ret]);
905 nret, 975 delay = GNUNET_TIME_absolute_get_duration (th->request_start);
906 ret); 976 if (delay.rel_value_us > 1000 * 1000)
977 LOG (GNUNET_ERROR_TYPE_WARNING,
978 "Added %u bytes of control message at %u after %s delay\n",
979 nret,
980 ret,
981 GNUNET_STRINGS_relative_time_to_string (delay,
982 GNUNET_YES));
983 else
984 LOG (GNUNET_ERROR_TYPE_DEBUG,
985 "Added %u bytes of control message at %u after %s delay\n",
986 nret,
987 ret,
988 GNUNET_STRINGS_relative_time_to_string (delay,
989 GNUNET_YES));
907 GNUNET_free (th); 990 GNUNET_free (th);
908 ret += nret; 991 ret += nret;
909 size -= nret; 992 size -= nret;
910 } 993 }
911 994
912 /* then, if possible and no control messages pending, send data messages */ 995 /* then, if possible and no control messages pending, send data messages */
913 while ((NULL == h->control_head) && 996 while ( (NULL == h->control_head) &&
914 (NULL != (n = GNUNET_CONTAINER_heap_peek (h->ready_heap)))) 997 (NULL != (n = GNUNET_CONTAINER_heap_peek (h->ready_heap))) )
915 { 998 {
916 if (GNUNET_YES != n->is_ready) 999 if (GNUNET_YES != n->is_ready)
917 { 1000 {
@@ -919,8 +1002,8 @@ transport_notify_ready (void *cls,
919 GNUNET_assert (n == GNUNET_CONTAINER_heap_remove_root (h->ready_heap)); 1002 GNUNET_assert (n == GNUNET_CONTAINER_heap_remove_root (h->ready_heap));
920 n->hn = NULL; 1003 n->hn = NULL;
921 GNUNET_assert (NULL == n->th->timeout_task); 1004 GNUNET_assert (NULL == n->th->timeout_task);
922 n->th->timeout_task = 1005 n->th->timeout_task
923 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining 1006 = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining
924 (n->th->timeout), 1007 (n->th->timeout),
925 &timeout_request_due_to_congestion, 1008 &timeout_request_due_to_congestion,
926 n->th); 1009 n->th);
@@ -935,14 +1018,20 @@ transport_notify_ready (void *cls,
935 GNUNET_assert (n == GNUNET_CONTAINER_heap_remove_root (h->ready_heap)); 1018 GNUNET_assert (n == GNUNET_CONTAINER_heap_remove_root (h->ready_heap));
936 n->hn = NULL; 1019 n->hn = NULL;
937 n->th = NULL; 1020 n->th = NULL;
938 n->is_ready = GNUNET_NO; 1021 n->is_ready = GNUNET_NO; // FIXME! move into 'if' below!
939 GNUNET_assert (size >= sizeof (struct OutboundMessage)); 1022 GNUNET_assert (size >= sizeof (struct OutboundMessage));
940 mret = 1023 mret =
941 th->notify (th->notify_cls, size - sizeof (struct OutboundMessage), 1024 th->notify (th->notify_cls, size - sizeof (struct OutboundMessage),
942 &cbuf[ret + sizeof (struct OutboundMessage)]); 1025 &cbuf[ret + sizeof (struct OutboundMessage)]);
943 GNUNET_assert (mret <= size - sizeof (struct OutboundMessage)); 1026 GNUNET_assert (mret <= size - sizeof (struct OutboundMessage));
944 if (mret != 0) 1027 if (0 != mret)
945 { 1028 {
1029 if (NULL != n->unready_warn_task)
1030 n->unready_warn_task
1031 = GNUNET_SCHEDULER_add_delayed (UNREADY_WARN_TIME,
1032 &do_warn_unready,
1033 n);
1034 n->last_payload = GNUNET_TIME_absolute_get ();
946 GNUNET_assert (mret + sizeof (struct OutboundMessage) < 1035 GNUNET_assert (mret + sizeof (struct OutboundMessage) <
947 GNUNET_SERVER_MAX_MESSAGE_SIZE); 1036 GNUNET_SERVER_MAX_MESSAGE_SIZE);
948 obm.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SEND); 1037 obm.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SEND);
@@ -952,10 +1041,28 @@ transport_notify_ready (void *cls,
952 GNUNET_TIME_relative_hton (GNUNET_TIME_absolute_get_remaining 1041 GNUNET_TIME_relative_hton (GNUNET_TIME_absolute_get_remaining
953 (th->timeout)); 1042 (th->timeout));
954 obm.peer = n->id; 1043 obm.peer = n->id;
955 memcpy (&cbuf[ret], &obm, sizeof (struct OutboundMessage)); 1044 memcpy (&cbuf[ret],
1045 &obm,
1046 sizeof (struct OutboundMessage));
956 ret += (mret + sizeof (struct OutboundMessage)); 1047 ret += (mret + sizeof (struct OutboundMessage));
957 size -= (mret + sizeof (struct OutboundMessage)); 1048 size -= (mret + sizeof (struct OutboundMessage));
958 GNUNET_BANDWIDTH_tracker_consume (&n->out_tracker, mret); 1049 GNUNET_BANDWIDTH_tracker_consume (&n->out_tracker,
1050 mret);
1051 delay = GNUNET_TIME_absolute_get_duration (th->request_start);
1052 if (delay.rel_value_us > 1000 * 1000)
1053 LOG (GNUNET_ERROR_TYPE_WARNING,
1054 "Added %u bytes of payload message at %u after %s delay\n",
1055 mret,
1056 ret,
1057 GNUNET_STRINGS_relative_time_to_string (delay,
1058 GNUNET_YES));
1059 else
1060 LOG (GNUNET_ERROR_TYPE_DEBUG,
1061 "Added %u bytes of payload message at %u after %s delay\n",
1062 mret,
1063 ret,
1064 GNUNET_STRINGS_relative_time_to_string (delay,
1065 GNUNET_YES));
959 } 1066 }
960 GNUNET_free (th); 1067 GNUNET_free (th);
961 } 1068 }
@@ -987,8 +1094,8 @@ schedule_transmission_task (void *cls,
987 h->quota_task = NULL; 1094 h->quota_task = NULL;
988 GNUNET_assert (NULL != h->client); 1095 GNUNET_assert (NULL != h->client);
989 /* destroy all requests that have timed out */ 1096 /* destroy all requests that have timed out */
990 while ((NULL != (n = GNUNET_CONTAINER_heap_peek (h->ready_heap))) && 1097 while ( (NULL != (n = GNUNET_CONTAINER_heap_peek (h->ready_heap))) &&
991 (0 == GNUNET_TIME_absolute_get_remaining (n->th->timeout).rel_value_us)) 1098 (0 == GNUNET_TIME_absolute_get_remaining (n->th->timeout).rel_value_us) )
992 { 1099 {
993 /* notify client that the request could not be satisfied within 1100 /* notify client that the request could not be satisfied within
994 * the given time constraints */ 1101 * the given time constraints */
@@ -999,7 +1106,9 @@ schedule_transmission_task (void *cls,
999 LOG (GNUNET_ERROR_TYPE_DEBUG, 1106 LOG (GNUNET_ERROR_TYPE_DEBUG,
1000 "Signalling timeout for transmission to peer %s due to congestion\n", 1107 "Signalling timeout for transmission to peer %s due to congestion\n",
1001 GNUNET_i2s (&n->id)); 1108 GNUNET_i2s (&n->id));
1002 GNUNET_assert (0 == th->notify (th->notify_cls, 0, NULL)); 1109 GNUNET_assert (0 == th->notify (th->notify_cls,
1110 0,
1111 NULL));
1003 GNUNET_free (th); 1112 GNUNET_free (th);
1004 } 1113 }
1005 if (NULL != h->cth) 1114 if (NULL != h->cth)
@@ -1017,10 +1126,12 @@ schedule_transmission_task (void *cls,
1017 } 1126 }
1018 LOG (GNUNET_ERROR_TYPE_DEBUG, 1127 LOG (GNUNET_ERROR_TYPE_DEBUG,
1019 "Calling notify_transmit_ready\n"); 1128 "Calling notify_transmit_ready\n");
1020 h->cth = 1129 h->cth
1021 GNUNET_CLIENT_notify_transmit_ready (h->client, size, 1130 = GNUNET_CLIENT_notify_transmit_ready (h->client,
1131 size,
1022 GNUNET_TIME_UNIT_FOREVER_REL, 1132 GNUNET_TIME_UNIT_FOREVER_REL,
1023 GNUNET_NO, &transport_notify_ready, 1133 GNUNET_NO,
1134 &transport_notify_ready,
1024 h); 1135 h);
1025 GNUNET_assert (NULL != h->cth); 1136 GNUNET_assert (NULL != h->cth);
1026} 1137}
@@ -1039,7 +1150,7 @@ schedule_transmission (struct GNUNET_TRANSPORT_Handle *h)
1039 struct Neighbour *n; 1150 struct Neighbour *n;
1040 1151
1041 GNUNET_assert (NULL != h->client); 1152 GNUNET_assert (NULL != h->client);
1042 if (h->quota_task != NULL) 1153 if (NULL != h->quota_task)
1043 { 1154 {
1044 GNUNET_SCHEDULER_cancel (h->quota_task); 1155 GNUNET_SCHEDULER_cancel (h->quota_task);
1045 h->quota_task = NULL; 1156 h->quota_task = NULL;
@@ -1057,9 +1168,12 @@ schedule_transmission (struct GNUNET_TRANSPORT_Handle *h)
1057 return; /* no work to be done */ 1168 return; /* no work to be done */
1058 LOG (GNUNET_ERROR_TYPE_DEBUG, 1169 LOG (GNUNET_ERROR_TYPE_DEBUG,
1059 "Scheduling next transmission to service in %s\n", 1170 "Scheduling next transmission to service in %s\n",
1060 GNUNET_STRINGS_relative_time_to_string (delay, GNUNET_YES)); 1171 GNUNET_STRINGS_relative_time_to_string (delay,
1172 GNUNET_YES));
1061 h->quota_task = 1173 h->quota_task =
1062 GNUNET_SCHEDULER_add_delayed (delay, &schedule_transmission_task, h); 1174 GNUNET_SCHEDULER_add_delayed (delay,
1175 &schedule_transmission_task,
1176 h);
1063} 1177}
1064 1178
1065 1179
@@ -1088,7 +1202,10 @@ schedule_control_transmit (struct GNUNET_TRANSPORT_Handle *h,
1088 th->notify = notify; 1202 th->notify = notify;
1089 th->notify_cls = notify_cls; 1203 th->notify_cls = notify_cls;
1090 th->notify_size = size; 1204 th->notify_size = size;
1091 GNUNET_CONTAINER_DLL_insert_tail (h->control_head, h->control_tail, th); 1205 th->request_start = GNUNET_TIME_absolute_get ();
1206 GNUNET_CONTAINER_DLL_insert_tail (h->control_head,
1207 h->control_tail,
1208 th);
1092 schedule_transmission (h); 1209 schedule_transmission (h);
1093 return th; 1210 return th;
1094} 1211}
@@ -1103,7 +1220,9 @@ schedule_control_transmit (struct GNUNET_TRANSPORT_Handle *h,
1103 * @return number of bytes copied to @a buf 1220 * @return number of bytes copied to @a buf
1104 */ 1221 */
1105static size_t 1222static size_t
1106send_start (void *cls, size_t size, void *buf) 1223send_start (void *cls,
1224 size_t size,
1225 void *buf)
1107{ 1226{
1108 struct GNUNET_TRANSPORT_Handle *h = cls; 1227 struct GNUNET_TRANSPORT_Handle *h = cls;
1109 struct StartMessage s; 1228 struct StartMessage s;
@@ -1124,7 +1243,7 @@ send_start (void *cls, size_t size, void *buf)
1124 options = 0; 1243 options = 0;
1125 if (h->check_self) 1244 if (h->check_self)
1126 options |= 1; 1245 options |= 1;
1127 if (h->rec != NULL) 1246 if (NULL != h->rec)
1128 options |= 2; 1247 options |= 2;
1129 s.options = htonl (options); 1248 s.options = htonl (options);
1130 s.self = h->self; 1249 s.self = h->self;
@@ -1845,17 +1964,17 @@ GNUNET_TRANSPORT_disconnect (struct GNUNET_TRANSPORT_Handle *handle)
1845 LOG (GNUNET_ERROR_TYPE_DEBUG, 1964 LOG (GNUNET_ERROR_TYPE_DEBUG,
1846 "Transport disconnect called!\n"); 1965 "Transport disconnect called!\n");
1847 /* this disconnects all neighbours... */ 1966 /* this disconnects all neighbours... */
1848 if (handle->reconnect_task == NULL) 1967 if (NULL == handle->reconnect_task)
1849 disconnect_and_schedule_reconnect (handle); 1968 disconnect_and_schedule_reconnect (handle);
1850 /* and now we stop trying to connect again... */ 1969 /* and now we stop trying to connect again... */
1851 if (handle->reconnect_task != NULL) 1970 if (NULL != handle->reconnect_task)
1852 { 1971 {
1853 GNUNET_SCHEDULER_cancel (handle->reconnect_task); 1972 GNUNET_SCHEDULER_cancel (handle->reconnect_task);
1854 handle->reconnect_task = NULL; 1973 handle->reconnect_task = NULL;
1855 } 1974 }
1856 GNUNET_CONTAINER_multipeermap_destroy (handle->neighbours); 1975 GNUNET_CONTAINER_multipeermap_destroy (handle->neighbours);
1857 handle->neighbours = NULL; 1976 handle->neighbours = NULL;
1858 if (handle->quota_task != NULL) 1977 if (NULL != handle->quota_task)
1859 { 1978 {
1860 GNUNET_SCHEDULER_cancel (handle->quota_task); 1979 GNUNET_SCHEDULER_cancel (handle->quota_task);
1861 handle->quota_task = NULL; 1980 handle->quota_task = NULL;
@@ -1921,6 +2040,7 @@ GNUNET_TRANSPORT_notify_transmit_ready (struct GNUNET_TRANSPORT_Handle *handle,
1921 th->neighbour = n; 2040 th->neighbour = n;
1922 th->notify = notify; 2041 th->notify = notify;
1923 th->notify_cls = notify_cls; 2042 th->notify_cls = notify_cls;
2043 th->request_start = GNUNET_TIME_absolute_get ();
1924 th->timeout = GNUNET_TIME_relative_to_absolute (timeout); 2044 th->timeout = GNUNET_TIME_relative_to_absolute (timeout);
1925 th->notify_size = size; 2045 th->notify_size = size;
1926 n->th = th; 2046 n->th = th;