@@ -50,6 +50,8 @@ struct IOCP_EVENT {
5050 int type ;
5151#define IOCP_EVENT_READ (1 << 0)
5252#define IOCP_EVENT_WRITE (1 << 2)
53+ #define IOCP_EVENT_DEAD (1 << 3)
54+
5355 ACL_EVENT_FDTABLE * fdp ;
5456
5557#define ACCEPT_ADDRESS_LENGTH ((sizeof(struct sockaddr_in) + 16))
@@ -73,20 +75,44 @@ static void stream_on_close(ACL_VSTREAM *stream, void *arg)
7375 }
7476
7577 /* 必须在释放 fdp->event_read/fdp->event_write 前关闭套接口句柄 */
76-
77- if (ACL_VSTREAM_SOCK (stream ) != ACL_SOCKET_INVALID && stream -> close_fn )
78+ shutdown (ACL_VSTREAM_SOCK (stream ), 0 );
79+ shutdown (ACL_VSTREAM_SOCK (stream ), 1 );
80+ if (ACL_VSTREAM_SOCK (stream ) != ACL_SOCKET_INVALID
81+ && stream -> close_fn )
82+ {
7883 (void ) stream -> close_fn (ACL_VSTREAM_SOCK (stream ));
79- else if (ACL_VSTREAM_FILE (stream ) != ACL_FILE_INVALID && stream -> fclose_fn )
84+ } else if (ACL_VSTREAM_FILE (stream ) != ACL_FILE_INVALID
85+ && stream -> fclose_fn )
86+ {
8087 (void ) stream -> fclose_fn (ACL_VSTREAM_FILE (stream ));
88+ }
89+
8190 ACL_VSTREAM_SOCK (stream ) = ACL_SOCKET_INVALID ;
8291 ACL_VSTREAM_FILE (stream ) = ACL_FILE_INVALID ;
8392
8493 if (fdp -> event_read ) {
85- acl_myfree (fdp -> event_read );
94+ /* 如果完成端口处于未决状态,则不能释放重叠结构,需在主循环的
95+ * GetQueuedCompletionStatus 调用后来释放
96+ */
97+ if (HasOverlappedIoCompleted (& fdp -> event_read -> overlapped ))
98+ acl_myfree (fdp -> event_read );
99+ else {
100+ fdp -> event_read -> type = IOCP_EVENT_DEAD ;
101+ fdp -> event_read -> fdp = NULL ;
102+ }
86103 fdp -> event_read = NULL ;
87104 }
88105 if (fdp -> event_write ) {
89- acl_myfree (fdp -> event_write );
106+ /* 如果完成端口处于未决状态,则不能释放重叠结构,需在主循环的
107+ * GetQueuedCompletionStatus 调用后来释放
108+ */
109+ if (HasOverlappedIoCompleted (& fdp -> event_write -> overlapped ))
110+ acl_myfree (fdp -> event_write );
111+ else {
112+ fdp -> event_write -> type = IOCP_EVENT_DEAD ;
113+ fdp -> event_write -> fdp = NULL ;
114+ }
115+
90116 fdp -> event_write = NULL ;
91117 }
92118
@@ -741,42 +767,64 @@ static void event_loop(ACL_EVENT *eventp)
741767 DWORD lastError = 0 ;
742768 IOCP_EVENT * iocp_event = NULL ;
743769
744- isSuccess = GetQueuedCompletionStatus (ev -> h_iocp , & bytesTransferred ,
745- (DWORD * ) & fdp , (OVERLAPPED * * ) & iocp_event , delay );
770+ isSuccess = GetQueuedCompletionStatus (ev -> h_iocp ,
771+ & bytesTransferred , (DWORD * ) & fdp ,
772+ (OVERLAPPED * * ) & iocp_event , delay );
773+
746774 if (!isSuccess ) {
747775 if (iocp_event == NULL )
748776 break ;
749- if (!(fdp -> event_type & (ACL_EVENT_XCPT | ACL_EVENT_RW_TIMEOUT ))) {
777+ if (iocp_event -> type == IOCP_EVENT_DEAD )
778+ acl_myfree (iocp_event );
779+ else if (iocp_event -> fdp == NULL ) {
780+ acl_msg_warn ("%s(%d): fdp null" ,
781+ myname , __LINE__ );
782+ acl_myfree (iocp_event );
783+ } else if (iocp_event -> fdp != fdp )
784+ acl_msg_fatal ("%s(%d): invalid fdp" ,
785+ myname , __LINE__ );
786+ else if (!(fdp -> event_type & (ACL_EVENT_XCPT
787+ | ACL_EVENT_RW_TIMEOUT )))
788+ {
750789 fdp -> event_type |= ACL_EVENT_XCPT ;
751790 fdp -> fdidx_ready = eventp -> fdcnt_ready ;
752- eventp -> fdtabs_ready [eventp -> fdcnt_ready ++ ] = fdp ;
791+ eventp -> fdtabs_ready [eventp -> fdcnt_ready ] = fdp ;
792+ eventp -> fdcnt_ready ++ ;
753793 }
754794 continue ;
755795 }
756796
757797 acl_assert (fdp == iocp_event -> fdp );
758798
759- if ((fdp -> event_type & (ACL_EVENT_XCPT | ACL_EVENT_RW_TIMEOUT )))
799+ if ((fdp -> event_type & (ACL_EVENT_XCPT
800+ | ACL_EVENT_RW_TIMEOUT )))
801+ {
760802 continue ;
803+ }
804+
761805 if (iocp_event -> type == IOCP_EVENT_READ ) {
762806 acl_assert (fdp -> event_read == iocp_event );
763807 iocp_event -> type &= ~IOCP_EVENT_READ ;
764808 fdp -> stream -> sys_read_ready = 1 ;
765- if ((fdp -> event_type & (ACL_EVENT_READ | ACL_EVENT_WRITE )) == 0 )
809+ if ((fdp -> event_type & (ACL_EVENT_READ
810+ | ACL_EVENT_WRITE )) == 0 )
766811 {
767812 fdp -> event_type |= ACL_EVENT_READ ;
768813 fdp -> fdidx_ready = eventp -> fdcnt_ready ;
769- eventp -> fdtabs_ready [eventp -> fdcnt_ready ++ ] = fdp ;
814+ eventp -> fdtabs_ready [eventp -> fdcnt_ready ] = fdp ;
815+ eventp -> fdcnt_ready ++ ;
770816 }
771817 }
772818 if (iocp_event -> type == IOCP_EVENT_WRITE ) {
773819 acl_assert (fdp -> event_write == iocp_event );
774820 iocp_event -> type &= ~IOCP_EVENT_WRITE ;
775- if ((fdp -> event_type & (ACL_EVENT_READ | ACL_EVENT_WRITE )) == 0 )
821+ if ((fdp -> event_type & (ACL_EVENT_READ
822+ | ACL_EVENT_WRITE )) == 0 )
776823 {
777824 fdp -> event_type |= ACL_EVENT_WRITE ;
778825 fdp -> fdidx_ready = eventp -> fdcnt_ready ;
779- eventp -> fdtabs_ready [eventp -> fdcnt_ready ++ ] = fdp ;
826+ eventp -> fdtabs_ready [eventp -> fdcnt_ready ] = fdp ;
827+ eventp -> fdcnt_ready ++ ;
780828 }
781829 }
782830 delay = 0 ;
0 commit comments