| 1330 | } |
| 1331 | |
| 1332 | static int tcp_pool_init(void) |
| 1333 | { |
| 1334 | int i; |
| 1335 | int started = 0; |
| 1336 | int threads_no; |
| 1337 | long cpu_no; |
| 1338 | |
| 1339 | if (tcp_threads > 0) |
| 1340 | threads_no = tcp_threads; |
| 1341 | else { |
| 1342 | cpu_no = sysconf(_SC_NPROCESSORS_ONLN); |
| 1343 | if (cpu_no > 0) |
| 1344 | threads_no = (int)cpu_no; |
| 1345 | else if (tcp_workers_no > 0) |
| 1346 | threads_no = tcp_workers_no; |
| 1347 | else |
| 1348 | threads_no = 1; |
| 1349 | } |
| 1350 | |
| 1351 | if (pipe(tcp_pool.notify_pipe) < 0) { |
| 1352 | LM_ERR("failed to create TCP IO notification pipe: %s\n", strerror(errno)); |
| 1353 | goto error; |
| 1354 | } |
| 1355 | |
| 1356 | if (tcp_set_nonblock(tcp_pool.notify_pipe[0]) < 0 || |
| 1357 | tcp_set_nonblock(tcp_pool.notify_pipe[1]) < 0) |
| 1358 | goto error; |
| 1359 | |
| 1360 | if (reactor_add_reader(tcp_pool.notify_pipe[0], |
| 1361 | F_TCP_NOTIFY, RCT_PRIO_PROC, NULL) < 0) { |
| 1362 | LM_ERR("failed to add TCP IO notify pipe to reactor\n"); |
| 1363 | goto error; |
| 1364 | } |
| 1365 | |
| 1366 | tcp_pool.threads = pkg_malloc(sizeof(*tcp_pool.threads) * threads_no); |
| 1367 | if (!tcp_pool.threads) { |
| 1368 | LM_ERR("oom while allocating TCP IO threads array\n"); |
| 1369 | goto error; |
| 1370 | } |
| 1371 | |
| 1372 | tcp_pool.stop = 0; |
| 1373 | tcp_pool.threads_no = threads_no; |
| 1374 | |
| 1375 | for (i = 0; i < threads_no; i++) { |
| 1376 | if (pthread_create(&tcp_pool.threads[i], NULL, |
| 1377 | tcp_thread_routine, NULL) != 0) { |
| 1378 | LM_ERR("failed to start TCP IO thread %d/%d\n", i + 1, threads_no); |
| 1379 | goto error; |
| 1380 | } |
| 1381 | started++; |
| 1382 | } |
| 1383 | |
| 1384 | LM_NOTICE("TCP single IO mode started with %d threads\n", threads_no); |
| 1385 | return 0; |
| 1386 | |
| 1387 | error: |
| 1388 | cond_lock(&tcp_write_queue->cond); |
| 1389 | tcp_pool.stop = 1; |
no test coverage detected