Skip to content

Commit 1934c31

Browse files
committed
Fixed udp segment fault
1 parent 4da7cfb commit 1934c31

File tree

5 files changed

+86
-50
lines changed

5 files changed

+86
-50
lines changed

examples/udp_server.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
22
$serv = new swoole_server("127.0.0.1", 9502, SWOOLE_PROCESS, SWOOLE_SOCK_UDP);
33
$serv->set(array(
4-
//'worker_num' => 4, //worker process num
4+
'worker_num' => 4, //worker process num
55
//'log_file' => '/tmp/swoole.log',
66
//'daemonize' => true,
77
));

include/Server.h

Lines changed: 1 addition & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -517,50 +517,7 @@ static sw_inline swWorker* swServer_get_worker(swServer *serv, uint16_t worker_i
517517
}
518518
}
519519

520-
static sw_inline int swServer_worker_schedule(swServer *serv, int schedule_key)
521-
{
522-
int target_worker_id = 0;
523-
524-
//polling mode
525-
if (serv->dispatch_mode == SW_DISPATCH_ROUND)
526-
{
527-
target_worker_id = (serv->worker_round_id++) % serv->worker_num;
528-
}
529-
//Using the FD touch access to hash
530-
else if (serv->dispatch_mode == SW_DISPATCH_FDMOD)
531-
{
532-
target_worker_id = schedule_key % serv->worker_num;
533-
}
534-
//Preemptive distribution
535-
else
536-
{
537-
if (serv->ipc_mode == SW_IPC_MSGQUEUE)
538-
{
539-
//msgsnd参数必须>0
540-
//worker进程中正确的mtype应该是pti + 1
541-
target_worker_id = serv->worker_num;
542-
}
543-
else
544-
{
545-
int i;
546-
sw_atomic_t *round = &SwooleTG.worker_round_i;
547-
for (i = 0; i < serv->worker_num; i++)
548-
{
549-
sw_atomic_fetch_add(round, 1);
550-
target_worker_id = (*round) % serv->worker_num;
551-
552-
if (serv->workers[target_worker_id].status == SW_WORKER_IDLE)
553-
{
554-
break;
555-
}
556-
}
557-
swTrace("schedule=%d|round=%d\n", target_worker_id, *round);
558-
}
559-
}
560-
return target_worker_id;
561-
}
562-
563-
static sw_inline int swServer_send2worker_blocking(swServer *serv, void *data, int len, int target_worker_id)
520+
static sw_inline int swServer_send2worker_blocking(swServer *serv, void *data, int len, uint16_t target_worker_id)
564521
{
565522
int ret = -1;
566523
swWorker *worker = &(serv->workers[target_worker_id]);

include/swoole.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -895,6 +895,7 @@ enum SW_CHANNEL_FLAGS
895895
SW_CHAN_SHM = 1u << 3,
896896
#define SW_CHAN_SHM SW_CHAN_SHM
897897
};
898+
898899
typedef struct _swChannel
899900
{
900901
int head; //头部,出队列方向
@@ -920,6 +921,15 @@ int swChannel_notify(swChannel *object);
920921
void swChannel_free(swChannel *object);
921922

922923
/*----------------------------Thread Pool-------------------------------*/
924+
enum swThread_type
925+
{
926+
SW_THREAD_REACTOR,
927+
SW_THREAD_WRITER,
928+
SW_THREAD_UDP,
929+
SW_THREAD_UNIX_DGRAM,
930+
SW_THREAD_HEARTBEAT,
931+
};
932+
923933
typedef struct _swThreadPool
924934
{
925935
pthread_mutex_t mutex;
@@ -1032,6 +1042,7 @@ typedef struct
10321042
typedef struct
10331043
{
10341044
uint16_t id;
1045+
uint8_t type;
10351046
uint8_t factory_lock_target;
10361047
int16_t factory_target_worker;
10371048
sw_atomic_t worker_round_i;

src/factory/FactoryProcess.c

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -873,17 +873,61 @@ int swFactoryProcess_notify(swFactory *factory, swDataHead *ev)
873873
return factory->dispatch(factory, (swDispatchData *) &sw_notify_data);
874874
}
875875

876+
877+
static sw_inline uint32_t swServer_worker_schedule(swServer *serv, uint32_t schedule_key)
878+
{
879+
uint32_t target_worker_id = 0;
880+
881+
//polling mode
882+
if (serv->dispatch_mode == SW_DISPATCH_ROUND)
883+
{
884+
target_worker_id = (serv->worker_round_id++) % serv->worker_num;
885+
}
886+
//Using the FD touch access to hash
887+
else if (serv->dispatch_mode == SW_DISPATCH_FDMOD)
888+
{
889+
target_worker_id = schedule_key % serv->worker_num;
890+
}
891+
//Preemptive distribution
892+
else
893+
{
894+
if (serv->ipc_mode == SW_IPC_MSGQUEUE)
895+
{
896+
//msgsnd参数必须>0
897+
//worker进程中正确的mtype应该是pti + 1
898+
target_worker_id = serv->worker_num;
899+
}
900+
else
901+
{
902+
int i;
903+
sw_atomic_t *round = &SwooleTG.worker_round_i;
904+
for (i = 0; i < serv->worker_num; i++)
905+
{
906+
sw_atomic_fetch_add(round, 1);
907+
target_worker_id = (*round) % serv->worker_num;
908+
909+
if (serv->workers[target_worker_id].status == SW_WORKER_IDLE)
910+
{
911+
break;
912+
}
913+
}
914+
swTrace("schedule=%d|round=%d\n", target_worker_id, *round);
915+
}
916+
}
917+
return target_worker_id;
918+
}
919+
876920
/**
877921
* [ReactorThread] dispatch request to worker
878922
*/
879923
int swFactoryProcess_dispatch(swFactory *factory, swDispatchData *task)
880924
{
881-
int schedule_key;
882-
int send_len = sizeof(task->data.info) + task->data.info.len;
883-
int target_worker_id = task->target_worker_id;
925+
uint32_t schedule_key;
926+
uint32_t send_len = sizeof(task->data.info) + task->data.info.len;
927+
uint16_t target_worker_id;
884928
swServer *serv = SwooleG.serv;
885929

886-
if (target_worker_id < 0)
930+
if (task->target_worker_id < 0)
887931
{
888932
//udp use remote port
889933
if (task->data.info.type == SW_EVENT_UDP || task->data.info.type == SW_EVENT_UDP6
@@ -915,7 +959,20 @@ int swFactoryProcess_dispatch(swFactory *factory, swDispatchData *task)
915959
target_worker_id = swServer_worker_schedule(serv, schedule_key);
916960
}
917961
}
918-
return swReactorThread_send2worker((void *) &(task->data), send_len, target_worker_id);
962+
else
963+
{
964+
target_worker_id = task->target_worker_id;
965+
}
966+
967+
if (SwooleTG.type == SW_THREAD_REACTOR)
968+
{
969+
return swReactorThread_send2worker((void *) &(task->data), send_len, target_worker_id);
970+
}
971+
else
972+
{
973+
swTrace("dispatch to worker#%d", target_worker_id);
974+
return swServer_send2worker_blocking(serv, (void *) &(task->data), send_len, target_worker_id);
975+
}
919976
}
920977

921978
static int swFactoryProcess_writer_start(swFactory *factory)

src/network/ReactorThread.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,6 +1030,7 @@ static int swReactorThread_loop_tcp(swThreadParam *param)
10301030
SwooleTG.factory_lock_target = 0;
10311031
SwooleTG.factory_target_worker = -1;
10321032
SwooleTG.id = reactor_id;
1033+
SwooleTG.type = SW_THREAD_REACTOR;
10331034

10341035
swReactorThread *thread = swServer_get_thread(serv, reactor_id);
10351036
swReactor *reactor = &thread->reactor;
@@ -1178,6 +1179,11 @@ static int swReactorThread_loop_udp(swThreadParam *param)
11781179

11791180
int sock = param->pti;
11801181

1182+
SwooleTG.factory_lock_target = 0;
1183+
SwooleTG.factory_target_worker = -1;
1184+
SwooleTG.id = sock;
1185+
SwooleTG.type = SW_THREAD_UDP;
1186+
11811187
swSignal_none();
11821188

11831189
//blocking
@@ -1374,6 +1380,11 @@ static int swReactorThread_loop_unix_dgram(swThreadParam *param)
13741380
uint16_t sun_path_offset;
13751381
uint8_t sun_path_len;
13761382

1383+
SwooleTG.factory_lock_target = 0;
1384+
SwooleTG.factory_target_worker = -1;
1385+
SwooleTG.id = param->pti;
1386+
SwooleTG.type = SW_THREAD_UNIX_DGRAM;
1387+
13771388
swSignal_none();
13781389

13791390
//blocking

0 commit comments

Comments
 (0)