Skip to content

Commit 9e5880e

Browse files
committed
Move implicit wsa startup. Renaming of TcpSocketPair.free. Remove wsaCleanup. Added finalizer for implicit close of wsa.
1 parent 53e4331 commit 9e5880e

File tree

4 files changed

+66
-13
lines changed

4 files changed

+66
-13
lines changed

lib/std/net/os/win32.c3

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
module std::net::os @if(env::WIN32);
2-
import std::os, std::io, libc;
2+
import std::os, std::io, libc, std::thread;
3+
import std::core::mem;
4+
import std::os::win32;
5+
6+
37

48
const AIFamily PLATFORM_AF_IPX = 6;
59
const AIFamily PLATFORM_AF_APPLETALK = 16;
@@ -23,6 +27,33 @@ extern fn int listen(NativeSocket, int backlog);
2327
extern fn NativeSocket accept(NativeSocket, SockAddrPtr address, Socklen_t* address_len);
2428
extern fn CInt getsockname(NativeSocket socket, SockAddrPtr address, Socklen_t* address_len);
2529

30+
char[408] wsa_data @local;
31+
int wsa_init @local;
32+
33+
macro void? start_wsa()
34+
{
35+
if (mem::compare_exchange(&wsa_init, 0, 2) == 2)
36+
{
37+
Win32_WORD version = 0x0202;
38+
CInt wsa_error = win32::wsaStartup(version, &wsa_data);
39+
if (wsa_error > 0)
40+
{
41+
mem::@atomic_store(wsa_init, 0);
42+
return os::socket_error()?;
43+
}
44+
mem::@atomic_store(wsa_init, 1);
45+
}
46+
}
47+
48+
fn void close_wsa() @local @finalizer
49+
{
50+
if (mem::compare_exchange(&wsa_init, 1, 3) == 3)
51+
{
52+
win32::wsaCleanup();
53+
mem::@atomic_store(wsa_init, 0);
54+
}
55+
}
56+
2657
macro bool NativeSocket.is_valid(self)
2758
{
2859
return self != (NativeSocket)(uptr)-1;

lib/std/net/socket_private.c3

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
module std::net @if(os::SUPPORTS_INET);
22
import std::time, libc, std::os;
3+
import std::core::env;
4+
import std::net::os;
5+
6+
37

48
macro void? apply_sockoptions(sockfd, options) @private
59
{
@@ -9,6 +13,9 @@ macro void? apply_sockoptions(sockfd, options) @private
913

1014
fn Socket? connect_from_addrinfo(AddrInfo* addrinfo, SocketOption[] options) @private
1115
{
16+
$if env::WIN32:
17+
os::start_wsa()!;
18+
$endif
1219
@loop_over_ai(addrinfo; NativeSocket sockfd, AddrInfo* ai)
1320
{
1421
apply_sockoptions(sockfd, options)!;
@@ -37,6 +44,9 @@ fn bool last_error_is_delayed_connect()
3744

3845
fn Socket? connect_with_timeout_from_addrinfo(AddrInfo* addrinfo, SocketOption[] options, Duration timeout) @private
3946
{
47+
$if env::WIN32:
48+
os::start_wsa()!;
49+
$endif
4050
Clock c = 0;
4151
@loop_over_ai(addrinfo; NativeSocket sockfd, AddrInfo* ai)
4252
{
@@ -82,6 +92,9 @@ fn Socket? connect_with_timeout_from_addrinfo(AddrInfo* addrinfo, SocketOption[]
8292

8393
fn Socket? connect_async_from_addrinfo(AddrInfo* addrinfo, SocketOption[] options) @private
8494
{
95+
$if env::WIN32:
96+
os::start_wsa()!;
97+
$endif
8598
@loop_over_ai(addrinfo; NativeSocket sockfd, AddrInfo* ai)
8699
{
87100
apply_sockoptions(sockfd, options)!;
@@ -98,6 +111,9 @@ fn Socket? connect_async_from_addrinfo(AddrInfo* addrinfo, SocketOption[] option
98111

99112
macro void @network_loop_over_ai(network, host, port; @body(fd, ai)) @private
100113
{
114+
$if env::WIN32:
115+
os::start_wsa()!;
116+
$endif
101117
AddrInfo* ai = network.addrinfo(host, port)!;
102118
AddrInfo* first = ai;
103119
defer os::freeaddrinfo(first);

lib/std/net/tcp.c3

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ module std::net::tcp @if(os::SUPPORTS_INET);
22
import std::net @public;
33
import std::time, libc;
44
import std::os::win32;
5+
import std::core::env;
6+
import std::net::os;
7+
8+
59

610
typedef TcpSocket = inline Socket;
711
typedef TcpServerSocket = inline Socket;
@@ -45,13 +49,19 @@ fn TcpSocket? accept(TcpServerSocket* server_socket)
4549
{
4650
TcpSocket socket;
4751
socket.ai_addrlen = socket.ai_addr_storage.len;
52+
$if env::WIN32:
53+
os::start_wsa()!;
54+
$endif
4855
socket.sock = os::accept(server_socket.sock, (SockAddrPtr)&socket.ai_addr_storage, &socket.ai_addrlen);
4956
if (!socket.sock.is_valid()) return net::ACCEPT_FAILED?;
5057
return socket;
5158
}
5259

5360
fn TcpServerSocket? listen_to(AddrInfo* ai, uint backlog, SocketOption... options)
5461
{
62+
$if env::WIN32:
63+
os::start_wsa()!;
64+
$endif
5565
net::@loop_over_ai(ai; NativeSocket sockfd, AddrInfo* ai_candidate)
5666
{
5767
net::apply_sockoptions(sockfd, options)!;
@@ -70,10 +80,7 @@ struct TcpSocketPair
7080
fn TcpSocketPair*? TcpSocketPair.init(&self)
7181
{
7282
$if env::WIN32:
73-
Win32_WORD version = 0x0202;
74-
char[408] wsa_data;
75-
CInt wsa_error = win32::wsaStartup(version, &wsa_data);
76-
if (wsa_error > 0) return os::socket_error()?;
83+
os::start_wsa()!;
7784

7885
TcpServerSocket listen_sock = tcp::listen("127.0.0.1", 0, 0)!;
7986

@@ -88,10 +95,10 @@ fn TcpSocketPair*? TcpSocketPair.init(&self)
8895
char lsb = listen_port_bytes[1];
8996
int listen_port = (msb << 8) | lsb;
9097

98+
defer (void)listen_sock.close();
9199
TcpSocket tcp_send_sock = tcp::connect_async("127.0.0.1", listen_port)!;
92100
TcpSocket tcp_recv_sock = tcp::accept(&listen_sock)!;
93101

94-
listen_sock.close()!;
95102
$else
96103
NativeSocket[2] sockets;
97104
isz sockpair_result = os::socketpair(os::AF_UNIX, os::SOCK_STREAM, 0, &sockets);
@@ -108,12 +115,11 @@ fn TcpSocketPair*? TcpSocketPair.init(&self)
108115
return self;
109116
}
110117

111-
fn void? TcpSocketPair.free(&self)
118+
fn void? TcpSocketPair.destroy(&self)
112119
{
113-
self.send.close()!;
120+
{
121+
defer catch (void)self.recv.close();
122+
self.send.close()!;
123+
}
114124
self.recv.close()!;
115-
116-
$if env::WIN32:
117-
win32::wsaCleanup();
118-
$endif
119125
}

test/unit/stdlib/net/tcp_socketpair.c3

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ fn void test_tcp_sock_pair()
55
{
66
tcp::TcpSocketPair sockets;
77
sockets.init()!!;
8-
defer sockets.free()!!;
8+
defer sockets.destroy()!!;
99

1010
String expected = "hello, world!";
1111
sockets.send.write(expected)!!;

0 commit comments

Comments
 (0)