I am trying to create a task that asynchronously accepts connection on a TCP socket initialized by external C code, something like this (simplified):
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
int make_socket(int port)
{
struct sockaddr_in addr = {0};
int sck = socket(AF_INET, SOCK_STREAM, 0);
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
bind(sck, (struct sockaddr *)&addr, sizeof(addr));
listen(sck, 1);
return sck;
}
Then I use this from Julia as follows:
new_sock(port) =ccall((:make_socket, "libtmp"), Cint, (Cint,), port)
mutable struct Sockaddr end
socket_accept(sockfd) = begin s_addr=Sockaddr();addr_len=Clonglong(0); ccall(:accept, Cint,(Cint,Ptr{Cvoid}, Ptr{Clonglong}),sockfd,Ref(s_addr),Ref(addr_len)); addr_len;end
The problem is that socket_accept()
blocks until a connection is made to the port. As far as I understand the problem, Julia threads use cooperative multitasking. So Base.Threads macro @spawn
and Distributed’s task creation macro @spawnat
do not return until the connection is made to the port. Is there some method to create a listener process that would not block Julia REPL?
(I know about Julia’s Sockets module, but need to use an externally created socket)