@@ -66,13 +66,65 @@ typedef struct _sock_mt sock_mt_t;
66
66
#define SOCK_MT_DEBUG (level , ...)
67
67
#endif
68
68
69
+ #if 0
69
70
#define SOCK_MT_LOCK (s , l ) \
70
71
{ \
71
72
SOCK_MT_DEBUG(1, "s %d l %d enter ", s, l); \
72
73
sys_mutex_lock(&sockets_mt[s].lock[l]); \
73
74
SOCK_MT_DEBUG(1, "OK\n"); \
74
75
}
75
76
77
+ #define SOCK_MT_LOCK_RET (s , l , r ) \
78
+ { \
79
+ SOCK_MT_LOCK(s, l); \
80
+ r = ERR_OK; \
81
+ }
82
+ #else
83
+ #define SOCK_MT_LOCK (s , l ) \
84
+ { \
85
+ SOCK_MT_DEBUG(1, "s %d l %d enter ", s, l); \
86
+ while (1) { \
87
+ err_t err; \
88
+ SYS_ARCH_DECL_PROTECT(lev); \
89
+ \
90
+ SYS_ARCH_PROTECT(lev); \
91
+ if (sockets_mt[s].lock[l]) \
92
+ err = sys_mutex_trylock(&sockets_mt[s].lock[l]); \
93
+ else \
94
+ err = ERR_VAL; \
95
+ SYS_ARCH_UNPROTECT(lev); \
96
+ \
97
+ if (err == ERR_OK) \
98
+ break; \
99
+ else if (err == ERR_VAL) \
100
+ return -1; \
101
+ \
102
+ vTaskDelay(1); \
103
+ } \
104
+ SOCK_MT_DEBUG(1, "OK\n"); \
105
+ }
106
+
107
+ #define SOCK_MT_LOCK_RET (s , l , r ) \
108
+ { \
109
+ SOCK_MT_DEBUG(1, "s %d l %d enter ", s, l); \
110
+ while (1) { \
111
+ SYS_ARCH_DECL_PROTECT(lev); \
112
+ \
113
+ SYS_ARCH_PROTECT(lev); \
114
+ if (sockets_mt[s].lock[l]) \
115
+ r = sys_mutex_trylock(&sockets_mt[s].lock[l]); \
116
+ else \
117
+ r = ERR_VAL; \
118
+ SYS_ARCH_UNPROTECT(lev); \
119
+ \
120
+ if (r == ERR_OK || ERR_VAL) \
121
+ break; \
122
+ vTaskDelay(1); \
123
+ } \
124
+ SOCK_MT_DEBUG(1, "OK\n"); \
125
+ }
126
+ #endif
127
+
76
128
#define SOCK_MT_TRYLOCK (s , l , r ) \
77
129
{ \
78
130
SOCK_MT_DEBUG(1, "s %d l %d try enter ", s, l); \
@@ -257,17 +309,21 @@ LOCAL int lwip_enter_mt_select(int s, int arg)
257
309
goto failed1 ;
258
310
259
311
if (FD_ISSET (i , read_set )) {
312
+ err_t err ;
313
+
260
314
SOCK_MT_SET_READ_SEL (i );
261
- SOCK_MT_LOCK (i , SOCK_MT_RECV_LOCK );
262
- if (SOCK_MT_GET_SHUTDOWN (i ) != SOCK_MT_SHUTDOWN_NONE ) {
315
+ SOCK_MT_LOCK_RET (i , SOCK_MT_RECV_LOCK , err );
316
+ if (err != ERR_OK || SOCK_MT_GET_SHUTDOWN (i ) != SOCK_MT_SHUTDOWN_NONE ) {
263
317
goto failed2 ;
264
318
}
265
319
}
266
320
267
321
if (FD_ISSET (i , write_set )) {
322
+ err_t err ;
323
+
268
324
SOCK_MT_SET_WRITE_SEL (i );
269
- SOCK_MT_LOCK (i , SOCK_MT_STATE_LOCK );
270
- if (SOCK_MT_GET_SHUTDOWN (i ) != SOCK_MT_SHUTDOWN_NONE ) {
325
+ SOCK_MT_LOCK_RET (i , SOCK_MT_STATE_LOCK , err );
326
+ if (err != ERR_OK || SOCK_MT_GET_SHUTDOWN (i ) != SOCK_MT_SHUTDOWN_NONE ) {
271
327
goto failed3 ;
272
328
}
273
329
}
@@ -408,6 +464,43 @@ LOCAL const ICACHE_RODATA_ATTR STORE_ATTR lwip_io_mt_fn lwip_exit_mt_table[] = {
408
464
lwip_exit_mt_close
409
465
};
410
466
467
+ LOCAL void lwip_do_sync_send (void * arg )
468
+ {
469
+ struct netconn * conn = arg ;
470
+
471
+ SYS_ARCH_DECL_PROTECT (lev );
472
+ SYS_ARCH_PROTECT (lev );
473
+ if (conn -> current_msg ) {
474
+ conn -> current_msg -> err = ERR_OK ;
475
+ conn -> current_msg = NULL ;
476
+ }
477
+ conn -> state = NETCONN_NONE ;
478
+ SYS_ARCH_UNPROTECT (lev );
479
+ if (sys_sem_valid (& (conn -> snd_op_completed )))
480
+ sys_sem_signal (& (conn -> snd_op_completed ));
481
+
482
+ /*
483
+ * if we use "op_completed" for its sync semaphore, then socket functions
484
+ * which are blocked by op_completed will be waked up.
485
+ *
486
+ * So we had better use a specific semaphore for the function, ioctrl_completed
487
+ * may be a good choise.
488
+ */
489
+ sys_sem_signal (& (conn -> ioctrl_completed ));
490
+ }
491
+
492
+ LOCAL void lwip_do_sync_rst_state (void * arg )
493
+ {
494
+ struct netconn * conn = arg ;
495
+
496
+ SYS_ARCH_DECL_PROTECT (lev );
497
+ SYS_ARCH_PROTECT (lev );
498
+ conn -> state = NETCONN_NONE ;
499
+ SYS_ARCH_UNPROTECT (lev );
500
+
501
+ sys_sem_signal (& (conn -> ioctrl_completed ));
502
+ }
503
+
411
504
LOCAL void lwip_sync_state_mt (struct lwip_sock * sock , int state )
412
505
{
413
506
SOCK_MT_DEBUG (1 , "sync state %d\n" , state );
@@ -419,16 +512,8 @@ LOCAL void lwip_sync_state_mt(struct lwip_sock *sock , int state)
419
512
break ;
420
513
case SOCK_MT_STATE_SEND :
421
514
{
422
- SYS_ARCH_DECL_PROTECT (lev );
423
- SYS_ARCH_PROTECT (lev );
424
- if (sock -> conn -> current_msg ) {
425
- sock -> conn -> current_msg -> err = ERR_OK ;
426
- sock -> conn -> current_msg = NULL ;
427
- }
428
- sock -> conn -> state = NETCONN_NONE ;
429
- SYS_ARCH_UNPROTECT (lev );
430
- if (sys_sem_valid (& (sock -> conn -> snd_op_completed )))
431
- sys_sem_signal (& (sock -> conn -> snd_op_completed ));
515
+ tcpip_callback (lwip_do_sync_send , sock -> conn );
516
+ sys_arch_sem_wait (& sock -> conn -> ioctrl_completed , 0 );
432
517
break ;
433
518
}
434
519
case SOCK_MT_STATE_CONNECT :
@@ -458,15 +543,19 @@ LOCAL void lwip_sync_mt(int s)
458
543
{
459
544
int module = 0 ;
460
545
int ret ;
546
+ struct lwip_sock * sock ;
461
547
462
548
while (module < SOCK_MT_SELECT ) {
463
549
extern void sys_arch_msleep (int ms );
464
550
int ret ;
465
- struct lwip_sock * sock ;
466
551
467
552
SOCK_MT_TRYLOCK (s , module , ret );
468
553
if (ret == ERR_OK ) {
469
- SOCK_MT_UNLOCK (s , module );
554
+ /*
555
+ * we always lock the mutex in case of other thread entering,
556
+ * other thread will be blocked at "SOCK_MT_LOCK" and poll-check
557
+ */
558
+ //SOCK_MT_UNLOCK(s, module);
470
559
module ++ ;
471
560
continue ;
472
561
}
@@ -494,6 +583,12 @@ LOCAL void lwip_sync_mt(int s)
494
583
495
584
sys_arch_msleep (LWIP_SYNC_MT_SLEEP_MS );
496
585
}
586
+
587
+ sock = tryget_socket (s );
588
+ if (sock ) {
589
+ tcpip_callback (lwip_do_sync_rst_state , sock -> conn );
590
+ sys_arch_sem_wait (& sock -> conn -> ioctrl_completed , 0 );
591
+ }
497
592
}
498
593
499
594
int lwip_socket_mt (int domain , int type , int protocol )
@@ -764,6 +859,8 @@ int lwip_close_mt(int s)
764
859
{
765
860
int ret ;
766
861
int i ;
862
+ SYS_ARCH_DECL_PROTECT (lev );
863
+ sys_mutex_t lock_tmp [SOCK_MT_LOCK_MAX ];
767
864
768
865
lwip_shutdown_mt (s , SHUT_RDWR );
769
866
@@ -773,10 +870,16 @@ int lwip_close_mt(int s)
773
870
774
871
LWIP_EXIT_MT (s , SOCK_MT_CLOSE , 0 );
775
872
873
+ SYS_ARCH_PROTECT (lev );
776
874
for (i = 0 ; i < SOCK_MT_LOCK_MAX ; i ++ ) {
777
- sys_mutex_free ( & sockets_mt [s ].lock [i ]) ;
875
+ lock_tmp [ i ] = sockets_mt [s ].lock [i ];
778
876
sockets_mt [s ].lock [i ] = NULL ;
779
877
}
878
+ SYS_ARCH_UNPROTECT (lev );
879
+
880
+ for (i = 0 ; i < SOCK_MT_LOCK_MAX ; i ++ ) {
881
+ sys_mutex_free (& lock_tmp [i ]);
882
+ }
780
883
781
884
return ret ;
782
885
}
0 commit comments