@@ -70,11 +70,13 @@ static ptk_err set_nonblocking(int fd) {
7070
7171// Helper function to create epoll instance and add socket
7272static ptk_err setup_epoll (ptk_sock * sock ) {
73+ debug ("setup_epoll: sock=%p, sock->fd=%d" , sock , sock -> fd );
7374 sock -> epoll_fd = epoll_create1 (EPOLL_CLOEXEC );
7475 if (sock -> epoll_fd == -1 ) {
75- error ("epoll_create1 failed: %s" , strerror (errno ));
76+ error ("setup_epoll: epoll_create1 failed: %s" , strerror (errno ));
7677 return PTK_ERR_NETWORK_ERROR ;
7778 }
79+ debug ("setup_epoll: created epoll_fd=%d" , sock -> epoll_fd );
7880
7981 // Create signal eventfd
8082 sock -> signal_fd = eventfd (0 , EFD_CLOEXEC | EFD_NONBLOCK );
@@ -93,9 +95,10 @@ static ptk_err setup_epoll(ptk_sock *sock) {
9395 return PTK_ERR_NETWORK_ERROR ;
9496 }
9597
96- // Add socket to epoll
98+ // Add socket to epoll - only register for EPOLLIN initially
99+ // EPOLLOUT will be added dynamically when needed for send operations
97100 struct epoll_event ev ;
98- ev .events = EPOLLIN | EPOLLOUT | EPOLLET ; // Edge-triggered
101+ ev .events = EPOLLIN ; // Only register for read events initially
99102 ev .data .fd = sock -> fd ;
100103 if (epoll_ctl (sock -> epoll_fd , EPOLL_CTL_ADD , sock -> fd , & ev ) == -1 ) {
101104 error ("epoll_ctl ADD socket failed: %s" , strerror (errno ));
@@ -161,37 +164,95 @@ static void socket_destructor(void *ptr) {
161164 }
162165}
163166
167+ // Helper to ensure socket is registered for specific events
168+ static ptk_err ensure_socket_events (ptk_sock * sock , uint32_t events ) {
169+ struct epoll_event ev ;
170+ ev .events = EPOLLIN | events ; // Always include EPOLLIN, add requested events
171+ ev .data .fd = sock -> fd ;
172+
173+ // Modify existing registration
174+ if (epoll_ctl (sock -> epoll_fd , EPOLL_CTL_MOD , sock -> fd , & ev ) == -1 ) {
175+ error ("epoll_ctl MOD socket failed: %s" , strerror (errno ));
176+ return PTK_ERR_NETWORK_ERROR ;
177+ }
178+
179+ return PTK_OK ;
180+ }
181+
182+ // Helper to reset socket events back to EPOLLIN only
183+ static ptk_err reset_socket_events (ptk_sock * sock ) {
184+ struct epoll_event ev ;
185+ ev .events = EPOLLIN ; // Only listen for incoming data
186+ ev .data .fd = sock -> fd ;
187+
188+ // Modify existing registration
189+ if (epoll_ctl (sock -> epoll_fd , EPOLL_CTL_MOD , sock -> fd , & ev ) == -1 ) {
190+ error ("epoll_ctl MOD socket failed: %s" , strerror (errno ));
191+ return PTK_ERR_NETWORK_ERROR ;
192+ }
193+
194+ return PTK_OK ;
195+ }
196+
164197// Helper to wait for socket events
165198static ptk_err wait_for_events (ptk_sock * sock , uint32_t events , ptk_duration_ms timeout_ms ) {
199+ info ("wait_for_events: sock=%p, events=0x%x, timeout=%d" , sock , events , timeout_ms );
200+ if (!sock ) {
201+ error ("wait_for_events: sock is NULL" );
202+ return PTK_ERR_INVALID_PARAM ;
203+ }
204+ info ("wait_for_events: sock->epoll_fd=%d, sock->fd=%d" , sock -> epoll_fd , sock -> fd );
205+
166206 struct epoll_event epoll_events [8 ];
167207 int timeout = (timeout_ms == 0 ) ? -1 : (int )timeout_ms ;
168208
209+ info ("wait_for_events: calling epoll_wait with timeout=%d" , timeout );
169210 int nfds = epoll_wait (sock -> epoll_fd , epoll_events , 8 , timeout );
211+ info ("wait_for_events: epoll_wait returned %d" , nfds );
170212 if (nfds == -1 ) {
213+ error ("wait_for_events: epoll_wait failed: %s (errno=%d)" , strerror (errno ), errno );
171214 if (errno == EINTR ) {
172215 return PTK_ERR_INTERRUPT ;
173216 }
174- error ("epoll_wait failed: %s" , strerror (errno ));
175217 return PTK_ERR_NETWORK_ERROR ;
176218 }
177219
178220 if (nfds == 0 ) {
221+ info ("wait_for_events: timeout occurred" );
179222 return PTK_ERR_TIMEOUT ;
180223 }
181224
225+ info ("wait_for_events: processing %d events" , nfds );
226+
182227 // Check for abort or signal
183228 for (int i = 0 ; i < nfds ; i ++ ) {
229+ info ("wait_for_events: event %d: fd=%d, events=0x%x" , i , epoll_events [i ].data .fd , epoll_events [i ].events );
230+ info ("wait_for_events: comparing with sock->fd=%d, sock->abort_fd=%d, sock->signal_fd=%d" ,
231+ sock -> fd , sock -> abort_fd , sock -> signal_fd );
232+
184233 if (epoll_events [i ].data .fd == sock -> abort_fd ) {
234+ info ("wait_for_events: abort event detected" );
185235 return PTK_ERR_ABORT ;
186236 }
187237 if (epoll_events [i ].data .fd == sock -> signal_fd ) {
238+ info ("wait_for_events: signal event detected" );
188239 return PTK_ERR_SIGNAL ;
189240 }
190- if (epoll_events [i ].data .fd == sock -> fd && (epoll_events [i ].events & events )) {
191- return PTK_OK ;
241+ if (epoll_events [i ].data .fd == sock -> fd ) {
242+ info ("wait_for_events: socket fd matched, checking events: got=0x%x, wanted=0x%x" ,
243+ epoll_events [i ].events , events );
244+ if (epoll_events [i ].events & events ) {
245+ info ("wait_for_events: socket event matched, returning PTK_OK" );
246+ return PTK_OK ;
247+ } else {
248+ info ("wait_for_events: socket fd matched but events don't match" );
249+ // For edge-triggered mode, we need to consume the event even if it doesn't match
250+ // what we're waiting for, so we continue processing other events
251+ }
192252 }
193253 }
194254
255+ info ("wait_for_events: no matching events found, returning PTK_ERR_WOULD_BLOCK" );
195256 return PTK_ERR_WOULD_BLOCK ;
196257}
197258
@@ -215,6 +276,7 @@ static void socket_thread_main(void *context) {
215276static ptk_sock * create_socket_with_thread (int fd , ptk_sock_type type ,
216277 ptk_socket_thread_func thread_func ,
217278 ptk_shared_handle_t shared_context ) {
279+ info ("create_socket_with_thread: fd=%d, type=%d" , fd , type );
218280 ptk_sock * sock = ptk_local_alloc (sizeof (ptk_sock ), socket_destructor );
219281 if (!sock ) {
220282 error ("Failed to allocate socket structure" );
@@ -230,6 +292,7 @@ static ptk_sock *create_socket_with_thread(int fd, ptk_sock_type type,
230292 sock -> user_func = thread_func ;
231293 sock -> shared_context = shared_context ;
232294 sock -> should_stop = false;
295+ info ("create_socket_with_thread: socket created with type=%d" , sock -> type );
233296
234297 // Set socket non-blocking
235298 if (set_nonblocking (fd ) != PTK_OK ) {
@@ -542,6 +605,12 @@ ptk_err ptk_tcp_socket_send(ptk_sock *sock, ptk_buf *data, ptk_duration_ms timeo
542605 size_t sent = 0 ;
543606
544607 while (sent < buf_size ) {
608+ // Ensure socket is registered for EPOLLOUT events
609+ ptk_err setup_result = ensure_socket_events (sock , EPOLLOUT );
610+ if (setup_result != PTK_OK ) {
611+ return setup_result ;
612+ }
613+
545614 // Wait for socket to be writable
546615 ptk_err wait_result = wait_for_events (sock , EPOLLOUT , timeout_ms );
547616 if (wait_result != PTK_OK ) {
@@ -560,18 +629,35 @@ ptk_err ptk_tcp_socket_send(ptk_sock *sock, ptk_buf *data, ptk_duration_ms timeo
560629 sent += result ;
561630 }
562631
632+ // Reset socket events back to EPOLLIN only after sending
633+ ptk_err reset_result = reset_socket_events (sock );
634+ if (reset_result != PTK_OK ) {
635+ return reset_result ;
636+ }
637+
563638 return PTK_OK ;
564639}
565640
566641ptk_buf * ptk_tcp_socket_recv (ptk_sock * sock , ptk_duration_ms timeout_ms ) {
567- if (!sock || sock -> type != PTK_SOCK_TCP_CLIENT ) {
642+ debug ("ptk_tcp_socket_recv: sock=%p, timeout=%d" , sock , timeout_ms );
643+ if (!sock ) {
644+ error ("ptk_tcp_socket_recv: sock is NULL" );
645+ ptk_set_err (PTK_ERR_INVALID_PARAM );
646+ return NULL ;
647+ }
648+ if (sock -> type != PTK_SOCK_TCP_CLIENT ) {
649+ error ("ptk_tcp_socket_recv: invalid socket type %d, expected %d" , sock -> type , PTK_SOCK_TCP_CLIENT );
568650 ptk_set_err (PTK_ERR_INVALID_PARAM );
569651 return NULL ;
570652 }
653+ debug ("ptk_tcp_socket_recv: validation passed, sock->fd=%d" , sock -> fd );
571654
572655 // Wait for data to be available
656+ debug ("ptk_tcp_socket_recv: calling wait_for_events with EPOLLIN" );
573657 ptk_err wait_result = wait_for_events (sock , EPOLLIN , timeout_ms );
658+ debug ("ptk_tcp_socket_recv: wait_for_events returned %d" , wait_result );
574659 if (wait_result != PTK_OK ) {
660+ error ("ptk_tcp_socket_recv: wait_for_events failed with %d" , wait_result );
575661 ptk_set_err (wait_result );
576662 return NULL ;
577663 }
@@ -621,6 +707,12 @@ ptk_err ptk_udp_socket_send_to(ptk_sock *sock, ptk_buf *data, const ptk_address_
621707 }
622708 }
623709
710+ // Ensure socket is registered for EPOLLOUT events
711+ ptk_err setup_result = ensure_socket_events (sock , EPOLLOUT );
712+ if (setup_result != PTK_OK ) {
713+ return setup_result ;
714+ }
715+
624716 // Wait for socket to be writable
625717 ptk_err wait_result = wait_for_events (sock , EPOLLOUT , timeout_ms );
626718 if (wait_result != PTK_OK ) {
@@ -652,14 +744,28 @@ ptk_err ptk_udp_socket_send_to(ptk_sock *sock, ptk_buf *data, const ptk_address_
652744 return PTK_ERR_NETWORK_ERROR ;
653745 }
654746
747+ // Reset socket events back to EPOLLIN only after sending
748+ ptk_err reset_result = reset_socket_events (sock );
749+ if (reset_result != PTK_OK ) {
750+ return reset_result ;
751+ }
752+
655753 return PTK_OK ;
656754}
657755
658756ptk_buf * ptk_udp_socket_recv_from (ptk_sock * sock , ptk_address_t * sender_addr , ptk_duration_ms timeout_ms ) {
659- if (!sock || sock -> type != PTK_SOCK_UDP ) {
757+ debug ("ptk_udp_socket_recv_from: sock=%p, sender_addr=%p, timeout=%d" , sock , sender_addr , timeout_ms );
758+ if (!sock ) {
759+ error ("ptk_udp_socket_recv_from: sock is NULL" );
760+ ptk_set_err (PTK_ERR_INVALID_PARAM );
761+ return NULL ;
762+ }
763+ if (sock -> type != PTK_SOCK_UDP ) {
764+ error ("ptk_udp_socket_recv_from: invalid socket type %d, expected %d" , sock -> type , PTK_SOCK_UDP );
660765 ptk_set_err (PTK_ERR_INVALID_PARAM );
661766 return NULL ;
662767 }
768+ info ("ptk_udp_socket_recv_from: validation passed, sock->fd=%d, sock->type=%d" , sock -> fd , sock -> type );
663769
664770 // If timeout is 0, loop to get all available packets
665771 if (timeout_ms == 0 ) {
@@ -669,8 +775,11 @@ ptk_buf *ptk_udp_socket_recv_from(ptk_sock *sock, ptk_address_t *sender_addr, pt
669775 }
670776
671777 // Wait for data to be available
778+ info ("ptk_udp_socket_recv_from: calling wait_for_events with EPOLLIN" );
672779 ptk_err wait_result = wait_for_events (sock , EPOLLIN , timeout_ms );
780+ info ("ptk_udp_socket_recv_from: wait_for_events returned %d" , wait_result );
673781 if (wait_result != PTK_OK ) {
782+ error ("ptk_udp_socket_recv_from: wait_for_events failed with %d" , wait_result );
674783 ptk_set_err (wait_result );
675784 return NULL ;
676785 }
0 commit comments