]>
Commit | Line | Data |
---|---|---|
3adbb389 | 1 | /* |
a3d5822a | 2 | * Copyright (C) 2016-2018 Red Hat, Inc. All rights reserved. |
3adbb389 FDN |
3 | * |
4 | * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org> | |
5 | * Federico Simoncelli <fsimon@kronosnet.org> | |
6 | * | |
7 | * This software licensed under GPL-2.0+, LGPL-2.0+ | |
8 | */ | |
9 | ||
10 | #include "config.h" | |
11 | ||
12 | #include <pthread.h> | |
13 | #include <errno.h> | |
14 | #include <string.h> | |
15 | ||
16 | #include "internals.h" | |
17 | #include "logging.h" | |
18 | #include "threads_common.h" | |
19 | ||
20 | int shutdown_in_progress(knet_handle_t knet_h) | |
21 | { | |
22 | int savederrno = 0; | |
23 | int ret; | |
24 | ||
25 | savederrno = pthread_rwlock_rdlock(&knet_h->global_rwlock); | |
26 | if (savederrno) { | |
27 | log_err(knet_h, KNET_SUB_COMMON, "Unable to get read lock: %s", | |
28 | strerror(savederrno)); | |
29 | errno = savederrno; | |
30 | return -1; | |
31 | } | |
32 | ||
33 | ret = knet_h->fini_in_progress; | |
34 | ||
35 | pthread_rwlock_unlock(&knet_h->global_rwlock); | |
36 | ||
37 | return ret; | |
38 | } | |
1dfc8220 FDN |
39 | |
40 | static int pmtud_reschedule(knet_handle_t knet_h) | |
41 | { | |
42 | if (pthread_mutex_lock(&knet_h->pmtud_mutex) != 0) { | |
43 | log_debug(knet_h, KNET_SUB_PMTUD, "Unable to get mutex lock"); | |
44 | return -1; | |
45 | } | |
46 | ||
d2a6344f FDN |
47 | if (knet_h->pmtud_running) { |
48 | knet_h->pmtud_abort = 1; | |
1dfc8220 | 49 | |
d2a6344f FDN |
50 | if (knet_h->pmtud_waiting) { |
51 | pthread_cond_signal(&knet_h->pmtud_cond); | |
52 | } | |
1dfc8220 FDN |
53 | } |
54 | ||
55 | pthread_mutex_unlock(&knet_h->pmtud_mutex); | |
56 | return 0; | |
57 | } | |
58 | ||
59 | int get_global_wrlock(knet_handle_t knet_h) | |
60 | { | |
61 | if (pmtud_reschedule(knet_h) < 0) { | |
62 | log_info(knet_h, KNET_SUB_PMTUD, "Unable to notify PMTUd to reschedule. Expect delays in executing API calls"); | |
63 | } | |
64 | return pthread_rwlock_wrlock(&knet_h->global_rwlock); | |
65 | } | |
aed6b5db | 66 | |
6394d892 | 67 | static struct pretty_names thread_names[KNET_THREAD_MAX] = |
3c77b62f FDN |
68 | { |
69 | { "TX", KNET_THREAD_TX }, | |
70 | { "RX", KNET_THREAD_RX }, | |
71 | { "HB", KNET_THREAD_HB }, | |
72 | { "PMTUD", KNET_THREAD_PMTUD }, | |
73 | #ifdef HAVE_NETINET_SCTP_H | |
74 | { "SCTP_LISTEN", KNET_THREAD_SCTP_LISTEN }, | |
75 | { "SCTP_CONN", KNET_THREAD_SCTP_CONN }, | |
76 | #endif | |
77 | { "DST_LINK", KNET_THREAD_DST_LINK } | |
78 | }; | |
79 | ||
80 | static struct pretty_names thread_status[] = | |
81 | { | |
6394d892 FDN |
82 | { "unregistered", KNET_THREAD_UNREGISTERED }, |
83 | { "registered", KNET_THREAD_REGISTERED }, | |
84 | { "started", KNET_THREAD_STARTED }, | |
85 | { "stopped", KNET_THREAD_STOPPED } | |
3c77b62f FDN |
86 | }; |
87 | ||
3c77b62f FDN |
88 | static const char *get_thread_status_name(uint8_t status) |
89 | { | |
90 | unsigned int i; | |
91 | ||
92 | for (i = 0; i < KNET_THREAD_STATUS_MAX; i++) { | |
93 | if (thread_status[i].val == status) { | |
94 | return thread_status[i].name; | |
95 | } | |
96 | } | |
97 | return "unknown"; | |
98 | } | |
99 | ||
100 | static const char *get_thread_name(uint8_t thread_id) | |
101 | { | |
102 | unsigned int i; | |
103 | ||
104 | for (i = 0; i < KNET_THREAD_MAX; i++) { | |
105 | if (thread_names[i].val == thread_id) { | |
106 | return thread_names[i].name; | |
107 | } | |
108 | } | |
109 | return "unknown"; | |
110 | } | |
111 | ||
aed6b5db FDN |
112 | int set_thread_status(knet_handle_t knet_h, uint8_t thread_id, uint8_t status) |
113 | { | |
114 | if (pthread_mutex_lock(&knet_h->threads_status_mutex) != 0) { | |
115 | log_debug(knet_h, KNET_SUB_HANDLE, "Unable to get mutex lock"); | |
116 | return -1; | |
117 | } | |
118 | ||
119 | knet_h->threads_status[thread_id] = status; | |
120 | ||
3c77b62f FDN |
121 | log_debug(knet_h, KNET_SUB_HANDLE, "Updated status for thread %s to %s", |
122 | get_thread_name(thread_id), get_thread_status_name(status)); | |
aed6b5db FDN |
123 | |
124 | pthread_mutex_unlock(&knet_h->threads_status_mutex); | |
125 | return 0; | |
126 | } | |
127 | ||
128 | int wait_all_threads_status(knet_handle_t knet_h, uint8_t status) | |
129 | { | |
130 | uint8_t i = 0, found = 0; | |
131 | ||
132 | while (!found) { | |
133 | usleep(KNET_THREADS_TIMERES); | |
134 | ||
135 | if (pthread_mutex_lock(&knet_h->threads_status_mutex) != 0) { | |
136 | continue; | |
137 | } | |
138 | ||
139 | found = 1; | |
140 | ||
141 | for (i = 0; i < KNET_THREAD_MAX; i++) { | |
6394d892 FDN |
142 | if (knet_h->threads_status[i] == KNET_THREAD_UNREGISTERED) { |
143 | continue; | |
144 | } | |
3c77b62f FDN |
145 | log_debug(knet_h, KNET_SUB_HANDLE, "Checking thread: %s status: %s req: %s", |
146 | get_thread_name(i), | |
147 | get_thread_status_name(knet_h->threads_status[i]), | |
148 | get_thread_status_name(status)); | |
aed6b5db FDN |
149 | if (knet_h->threads_status[i] != status) { |
150 | found = 0; | |
151 | } | |
152 | } | |
153 | ||
154 | pthread_mutex_unlock(&knet_h->threads_status_mutex); | |
155 | } | |
156 | ||
157 | return 0; | |
158 | } |