Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
H
http-server
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cython-plus
http-server
Commits
8cc525ba
Commit
8cc525ba
authored
Nov 01, 2021
by
Xavier Thompson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement GIL-free socket API
parent
7ea35116
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
196 additions
and
3 deletions
+196
-3
src/stdlib/_socket.pxd
src/stdlib/_socket.pxd
+6
-1
src/stdlib/socket.pxd
src/stdlib/socket.pxd
+190
-2
No files found.
src/stdlib/_socket.pxd
View file @
8cc525ba
...
@@ -3,7 +3,7 @@ cdef extern from "<sys/types.h>" nogil:
...
@@ -3,7 +3,7 @@ cdef extern from "<sys/types.h>" nogil:
cdef
extern
from
"<sys/socket.h>"
nogil
:
cdef
extern
from
"<sys/socket.h>"
n
amespace
""
n
ogil
:
ctypedef
long
socklen_t
ctypedef
long
socklen_t
...
@@ -55,6 +55,11 @@ cdef extern from "<sys/socket.h>" nogil:
...
@@ -55,6 +55,11 @@ cdef extern from "<sys/socket.h>" nogil:
int
socketpair
(
int
,
int
,
int
,
int
[
2
])
int
socketpair
(
int
,
int
,
int
,
int
[
2
])
cdef
extern
from
"<unistd.h>"
namespace
""
nogil
:
int
close
(
int
fd
)
cdef
extern
from
"<netdb.h>"
nogil
:
cdef
extern
from
"<netdb.h>"
nogil
:
...
...
src/stdlib/socket.pxd
View file @
8cc525ba
cimport
stdlib._socket
as
_socket
cimport
stdlib._socket
as
_socket
from
stdlib._string
cimport
string
,
move_string
from
libc.string
cimport
memset
,
memcpy
from
libc.errno
cimport
errno
from
libc.string
cimport
memset
,
memcpy
,
strerror
from
libc.stdlib
cimport
malloc
,
free
from
libc.stdlib
cimport
malloc
,
free
from
stdlib.string
cimport
Str
from
stdlib.string
cimport
Str
from
libcythonplus.list
cimport
cyplist
from
libcythonplus.list
cimport
cyplist
...
@@ -121,7 +123,7 @@ cdef cypclass Addrinfo:
...
@@ -121,7 +123,7 @@ cdef cypclass Addrinfo:
self
.
sockaddr
=
sockaddr
self
.
sockaddr
=
sockaddr
cdef
inline
cyplist
[
Addrinfo
]
getaddrinfo
(
Str
host
,
Str
port
,
int
family
,
int
socktype
,
int
protocol
,
int
flags
)
nogil
except
NULL
:
cdef
inline
cyplist
[
Addrinfo
]
getaddrinfo
(
Str
host
,
Str
port
,
int
family
=
0
,
int
socktype
=
0
,
int
protocol
=
0
,
int
flags
=
0
)
nogil
except
NULL
:
cdef
_socket
.
addrinfo
hints
cdef
_socket
.
addrinfo
hints
cdef
_socket
.
addrinfo
*
ai
cdef
_socket
.
addrinfo
*
ai
cdef
_socket
.
addrinfo
*
p
cdef
_socket
.
addrinfo
*
p
...
@@ -152,4 +154,190 @@ cdef inline cyplist[Addrinfo] getaddrinfo(Str host, Str port, int family, int so
...
@@ -152,4 +154,190 @@ cdef inline cyplist[Addrinfo] getaddrinfo(Str host, Str port, int family, int so
return
result
return
result
cdef
cypclass
Socket
cdef
inline
Socket
socket
(
int
family
,
int
socktype
,
int
protocol
=
0
)
nogil
except
NULL
:
cdef
int
sockfd
=
_socket
.
socket
(
family
,
socktype
,
protocol
)
if
sockfd
==
-
1
:
with
gil
:
raise
OSError
(
'failed to open socket: '
+
strerror
(
errno
).
decode
())
s
=
Socket
()
s
.
sockfd
=
sockfd
s
.
family
=
family
s
.
socktype
=
socktype
s
.
protocol
=
protocol
s
.
address
=
NULL
return
s
cdef
cypclass
Socket
:
int
sockfd
int
family
int
socktype
int
protocol
Sockaddr
address
int
setsockopt
(
self
,
int
optname
,
int
value
)
except
-
1
:
cdef
int
status
status
=
_socket
.
setsockopt
(
self
.
sockfd
,
SOL_SOCKET
,
optname
,
&
value
,
sizeof
(
value
))
if
status
==
-
1
:
with
gil
:
raise
OSError
(
'failed to set socket option: '
+
strerror
(
errno
).
decode
())
return
status
int
bind
(
self
,
Sockaddr
address
)
except
-
1
:
cdef
int
status
status
=
_socket
.
bind
(
self
.
sockfd
,
address
.
addr
,
address
.
addrlen
)
if
status
==
-
1
:
with
gil
:
raise
OSError
(
'failed to bind socket: '
+
strerror
(
errno
).
decode
())
self
.
address
=
address
return
status
int
connect
(
self
,
Sockaddr
address
)
except
-
1
:
cdef
int
status
status
=
_socket
.
connect
(
self
.
sockfd
,
address
.
addr
,
address
.
addrlen
)
if
status
==
-
1
:
with
gil
:
raise
OSError
(
'failed to connect socket: '
+
strerror
(
errno
).
decode
())
self
.
address
=
address
return
status
int
listen
(
self
,
int
backlog
)
except
-
1
:
cdef
int
status
status
=
_socket
.
listen
(
self
.
sockfd
,
backlog
)
if
status
==
-
1
:
with
gil
:
raise
OSError
(
'failed to listen to socket: '
+
strerror
(
errno
).
decode
())
return
status
Socket
accept
(
self
)
except
NULL
:
cdef
_socket
.
sockaddr_storage
addr
cdef
_socket
.
socklen_t
addrlen
cdef
int
status
cdef
Socket
socket
status
=
_socket
.
accept
(
self
.
sockfd
,
<
_socket
.
sockaddr
*>
&
addr
,
&
addrlen
)
if
status
==
-
1
:
with
gil
:
raise
OSError
(
'failed to accept from socket: '
+
strerror
(
errno
).
decode
())
socket
=
Socket
()
socket
.
sockfd
=
status
socket
.
family
=
self
.
family
socket
.
socktype
=
self
.
socktype
socket
.
protocol
=
self
.
protocol
socket
.
address
=
Sockaddr
(
<
_socket
.
sockaddr
*>
&
addr
,
addrlen
)
return
socket
int
send
(
self
,
Str
msg
,
int
flags
=
0
)
except
-
1
:
cdef
int
status
if
msg
is
NULL
:
with
gil
:
raise
ValueError
(
'cannot send NULL to socket'
)
status
=
_socket
.
send
(
self
.
sockfd
,
Str
.
to_c_str
(
msg
),
msg
.
__len__
(),
flags
)
if
status
==
-
1
:
with
gil
:
raise
OSError
(
'failed to send to socket: '
+
strerror
(
errno
).
decode
())
return
status
int
sendsubstr
(
self
,
Str
msg
,
int
flags
=
0
,
size_t
start
=
0
,
size_t
stop
=
0
)
except
-
1
:
cdef
int
status
if
msg
is
NULL
:
with
gil
:
raise
ValueError
(
'cannot send NULL to socket'
)
end
=
msg
.
__len__
()
if
stop
==
0
:
stop
=
end
elif
stop
>
end
:
with
gil
:
raise
ValueError
(
'slice bounds out of range'
)
if
start
>=
stop
:
with
gil
:
raise
ValueError
(
'slice bounds out of order'
)
size
=
stop
-
start
status
=
_socket
.
send
(
self
.
sockfd
,
Str
.
to_c_str
(
msg
)
+
start
,
size
,
flags
)
if
status
==
-
1
:
with
gil
:
raise
OSError
(
'failed to send to socket: '
+
strerror
(
errno
).
decode
())
return
status
int
sendall
(
self
,
Str
msg
,
int
flags
=
0
)
except
-
1
:
cdef
int
sent
=
self
.
send
(
msg
,
flags
)
cdef
int
size
=
msg
.
__len__
()
while
sent
<
size
:
sent
+=
self
.
sendsubstr
(
msg
,
flags
,
sent
)
return
sent
iso
Str
recv
(
self
,
int
bufsize
,
int
flags
=
0
)
except
NULL
:
cdef
int
status
# unnecessary zero-initialisation but unavoidable with C++<23 strings
cdef
string
buf
=
string
(
bufsize
,
<
char
>
0
)
cdef
iso
Str
result
status
=
_socket
.
recv
(
self
.
sockfd
,
&
buf
[
0
],
bufsize
,
flags
)
if
status
==
-
1
:
with
gil
:
raise
OSError
(
'failed to recv from socket: '
+
strerror
(
errno
).
decode
())
buf
.
resize
(
status
)
#if status < bufsize:
# buf.shrink_to_fit()
result
=
new
Str
()
result
.
_str
=
move_string
(
buf
)
return
consume
result
iso
Str
recvinto
(
self
,
iso
Str
result
,
int
bufsize
,
int
flags
=
0
)
except
NULL
:
cdef
int
status
cdef
int
oldsize
=
result
.
_str
.
size
()
# unnecessary zero-initialisation but unavoidable with C++<23 strings
result
.
_str
.
resize
(
oldsize
+
bufsize
)
status
=
_socket
.
recv
(
self
.
sockfd
,
&
(
result
.
_str
[
oldsize
]),
bufsize
,
flags
)
if
status
==
-
1
:
result
.
_str
.
resize
(
oldsize
)
with
gil
:
raise
OSError
(
'failed to recv from socket: '
+
strerror
(
errno
).
decode
())
result
.
_str
.
resize
(
oldsize
+
status
)
# if status < bufsize:
# result._str.shrink_to_fit()
return
consume
result
iso
Str
recvuntil
(
self
,
Str
sentinel
,
int
bufsize
,
int
flags
=
0
)
except
NULL
:
cdef
size_t
oldsize
=
0
cdef
Str
result
=
self
.
recv
(
bufsize
,
flags
)
cdef
size_t
newsize
=
result
.
_str
.
size
()
while
not
result
.
find
(
sentinel
,
oldsize
):
oldsize
=
newsize
result
=
self
.
recvinto
(
consume
result
,
bufsize
,
flags
)
newsize
=
result
.
_str
.
size
()
if
newsize
==
oldsize
:
break
return
consume
result
iso
Str
recvall
(
self
,
int
flags
=
0
)
except
NULL
:
cdef
int
bufsize
=
96
cdef
iso
Str
result
=
new
Str
()
result
.
_str
=
string
()
cdef
size_t
oldsize
=
result
.
_str
.
size
()
while
True
:
result
=
self
.
recvinto
(
consume
result
,
bufsize
,
flags
)
if
result
.
_str
.
size
()
==
oldsize
:
break
oldsize
=
result
.
_str
.
size
()
if
bufsize
<
4096
:
bufsize
=
bufsize
*
2
return
consume
result
int
shutdown
(
self
,
int
how
)
except
-
1
:
cdef
int
status
status
=
_socket
.
shutdown
(
self
.
sockfd
,
how
)
if
status
==
-
1
:
with
gil
:
raise
OSError
(
'failed to shutdown socket: '
+
strerror
(
errno
).
decode
())
return
status
int
close
(
self
)
except
-
1
:
cdef
int
status
status
=
_socket
.
close
(
self
.
sockfd
)
if
status
==
-
1
:
with
gil
:
raise
OSError
(
'failed to close socket: '
+
strerror
(
errno
).
decode
())
return
status
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment