The open source OpenXR runtime
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

d/remote: Properly shut down the run_thread

+65 -30
+65 -30
src/xrt/drivers/remote/r_hub.c
··· 104 104 return 0; 105 105 } 106 106 107 - int 108 - do_accept(struct r_hub *r) 107 + static bool 108 + wait_for_read_and_to_continue(struct r_hub *r, int socket) 109 109 { 110 - struct sockaddr_in addr = {0}; 111 110 struct timeval timeout = {.tv_sec = 1}; 112 111 fd_set set; 113 - int ret; 114 - int conn_fd; 112 + int ret = 0; 115 113 116 - // Shutting down. 117 - if (r->accept_fd < 0) { 118 - return -1; 114 + // To be more roboust 115 + if (socket < 0) { 116 + return false; 119 117 } 120 118 121 - do { 119 + while (os_thread_helper_is_running(&r->oth) && ret == 0) { 122 120 FD_ZERO(&set); 123 - FD_SET(r->accept_fd, &set); 121 + FD_SET(socket, &set); 124 122 125 - ret = select(r->accept_fd + 1, &set, NULL, NULL, &timeout); 126 - } while (ret == 0); 123 + ret = select(socket + 1, &set, NULL, NULL, &timeout); 124 + } 127 125 128 126 if (ret < 0) { 129 127 R_ERROR(r, "select: %i", ret); 130 - return ret; 128 + return false; 129 + } else if (ret > 0) { 130 + return true; 131 + } else { 132 + return false; 133 + } 134 + } 135 + 136 + int 137 + do_accept(struct r_hub *r) 138 + { 139 + struct sockaddr_in addr = {0}; 140 + int ret = 0; 141 + int conn_fd; 142 + 143 + if (!wait_for_read_and_to_continue(r, r->accept_fd)) { 144 + return -1; 131 145 } 132 146 133 147 socklen_t addr_length = (socklen_t)sizeof(addr); ··· 154 168 return 0; 155 169 } 156 170 171 + static int 172 + read_one(struct r_hub *r, struct r_remote_data *data) 173 + { 174 + struct r_remote_connection *rc = &r->rc; 175 + 176 + const size_t size = sizeof(*data); 177 + size_t current = 0; 178 + 179 + while (current < size) { 180 + void *ptr = (uint8_t *)data + current; 181 + 182 + if (!wait_for_read_and_to_continue(r, rc->fd)) { 183 + return -1; 184 + } 185 + 186 + ssize_t ret = read(rc->fd, ptr, size - current); 187 + if (ret < 0) { 188 + RC_ERROR(rc, "read: %zi", ret); 189 + return ret; 190 + } else if (ret > 0) { 191 + current += (size_t)ret; 192 + } else { 193 + R_INFO(r, "Disconnected!"); 194 + return -1; 195 + } 196 + } 197 + 198 + return 0; 199 + } 200 + 157 201 void * 158 202 run_thread(void *ptr) 159 203 { ··· 166 210 return NULL; 167 211 } 168 212 169 - while (r->accept_fd >= 0) { 213 + while (os_thread_helper_is_running(&r->oth)) { 170 214 R_INFO(r, "Listening on port '%i'.", r->port); 171 215 172 216 ret = do_accept(r); ··· 181 225 while (true) { 182 226 struct r_remote_data data; 183 227 184 - ret = r_remote_connection_read_one(&r->rc, &data); 228 + ret = read_one(r, &data); 185 229 if (ret < 0) { 186 230 break; 187 231 } ··· 200 244 { 201 245 struct r_hub *r = (struct r_hub *)xsysd; 202 246 203 - /* 204 - * Destroy all of the devices first. 205 - */ 247 + R_DEBUG(r, "Destroying"); 206 248 249 + // Stop the thread first. 250 + os_thread_helper_stop_and_wait(&r->oth); 251 + 252 + // Destroy all of the devices now. 207 253 for (uint32_t i = 0; i < ARRAY_SIZE(r->base.xdevs); i++) { 208 254 xrt_device_destroy(&r->base.xdevs[i]); 209 255 } 210 256 211 - 212 - /* 213 - * Harshly pull the plug on the sockets to wakeup the thread. 214 - */ 215 - 257 + // Should be safe to destroy the sockets now. 216 258 if (r->accept_fd >= 0) { 217 259 close(r->accept_fd); 218 260 r->accept_fd = -1; ··· 222 264 close(r->rc.fd); 223 265 r->rc.fd = -1; 224 266 } 225 - 226 - 227 - /* 228 - * Should be safe to stop the thread now. 229 - */ 230 - 231 - os_thread_helper_stop_and_wait(&r->oth); 232 267 233 268 free(r); 234 269 }