@@ -42,6 +42,55 @@ function buffer_send_data(input::Channel{T}) where T <: ProtoType
42
42
end
43
43
=#
44
44
45
+ function share_lock (easy_p:: Ptr{Cvoid} , data:: curl_lock_data , access:: curl_lock_access , userptr:: Ptr{Cvoid} )
46
+ share = unsafe_pointer_to_objref (Ptr {CurlShare} (userptr)):: CurlShare
47
+ lock (share. locks[data])
48
+ nothing
49
+ end
50
+
51
+ function share_unlock (easy_p:: Ptr{Cvoid} , data:: curl_lock_data , userptr:: Ptr{Cvoid} )
52
+ share = unsafe_pointer_to_objref (Ptr {CurlShare} (userptr)):: CurlShare
53
+ unlock (share. locks[data])
54
+ nothing
55
+ end
56
+
57
+ mutable struct CurlShare
58
+ shptr:: Ptr{CURLSH}
59
+ locks:: Vector{ReentrantLock}
60
+ closed:: Bool
61
+
62
+ function CurlShare ()
63
+ shptr = curl_share_init ()
64
+ curl_share_setopt (shptr, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE)
65
+ curl_share_setopt (shptr, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS)
66
+ curl_share_setopt (shptr, CURLSHOPT_SHARE, CURL_LOCK_DATA_PSL)
67
+
68
+ share_lock_cb = @cfunction (share_lock, Cvoid, (Ptr{Cvoid}, Cuint, Cuint, Ptr{Cvoid}))
69
+ share_unlock_cb = @cfunction (share_unlock, Cvoid, (Ptr{Cvoid}, Cuint, Ptr{Cvoid}))
70
+
71
+ @ccall LibCURL. LibCURL_jll. libcurl. curl_share_setopt (shptr:: Ptr{CURLSH} , CURLSHOPT_LOCKFUNC:: CURLSHoption ; share_lock_cb:: Ptr{Cvoid} ):: CURLSHcode
72
+ @ccall LibCURL. LibCURL_jll. libcurl. curl_share_setopt (shptr:: Ptr{CURLSH} , CURLSHOPT_UNLOCKFUNC:: CURLSHoption ; share_unlock_cb:: Ptr{Cvoid} ):: CURLSHcode
73
+
74
+ locks = Vector (undef, CURL_LOCK_DATA_LAST)
75
+ for idx in 1 : CURL_LOCK_DATA_LAST
76
+ locks[idx] = ReentrantLock ()
77
+ end
78
+
79
+ obj = new (shptr, locks, false )
80
+ userptr = pointer_from_objref (obj)
81
+ @ccall LibCURL. LibCURL_jll. libcurl. curl_share_setopt (shptr:: Ptr{CURLSH} , CURLSHOPT_USERDATA:: CURLSHoption ; userptr:: Ptr{Cvoid} ):: CURLSHcode
82
+ obj
83
+ end
84
+ end
85
+
86
+ function close (share:: CurlShare )
87
+ if share. closed
88
+ curl_share_cleanup (share. shptr)
89
+ share. closed = true
90
+ end
91
+ nothing
92
+ end
93
+
45
94
function send_data (easy:: Curl.Easy , input:: Channel{T} , max_send_message_length:: Int ) where T <: ProtoType
46
95
while true
47
96
yield ()
@@ -95,7 +144,7 @@ function grpc_request_header(request_timeout::Real)
95
144
end
96
145
end
97
146
98
- function easy_handle (maxage:: Clong , keepalive:: Clong , negotiation:: Symbol , revocation:: Bool , request_timeout:: Real )
147
+ function easy_handle (curlshare :: Ptr{CURLSH} , maxage:: Clong , keepalive:: Clong , negotiation:: Symbol , revocation:: Bool , request_timeout:: Real )
99
148
easy = Curl. Easy ()
100
149
http_version = (negotiation === :http2 ) ? CURL_HTTP_VERSION_2_0 :
101
150
(negotiation === :http2_tls ) ? CURL_HTTP_VERSION_2TLS :
@@ -105,6 +154,7 @@ function easy_handle(maxage::Clong, keepalive::Clong, negotiation::Symbol, revoc
105
154
Curl. setopt (easy, CURLOPT_PIPEWAIT, Clong (1 ))
106
155
Curl. setopt (easy, CURLOPT_POST, Clong (1 ))
107
156
Curl. setopt (easy, CURLOPT_HTTPHEADER, grpc_request_header (request_timeout))
157
+ Curl. setopt (easy, CURLOPT_SHARE, curlshare)
108
158
if ! revocation
109
159
Curl. setopt (easy, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE)
110
160
end
@@ -172,7 +222,7 @@ function set_connect_timeout(easy::Curl.Easy, timeout::Real)
172
222
end
173
223
end
174
224
175
- function grpc_request (downloader:: Downloader , url:: String , input:: Channel{T1} , output:: Channel{T2} ;
225
+ function grpc_request (curlshare :: Ptr{CURLSH} , downloader:: Downloader , url:: String , input:: Channel{T1} , output:: Channel{T2} ;
176
226
maxage:: Clong = typemax (Clong),
177
227
keepalive:: Clong = 60 ,
178
228
negotiation:: Symbol = :http2_prior_knowledge ,
@@ -182,7 +232,7 @@ function grpc_request(downloader::Downloader, url::String, input::Channel{T1}, o
182
232
max_recv_message_length:: Int = DEFAULT_MAX_RECV_MESSAGE_LENGTH,
183
233
max_send_message_length:: Int = DEFAULT_MAX_SEND_MESSAGE_LENGTH,
184
234
verbose:: Bool = false ):: gRPCStatus where {T1 <: ProtoType , T2 <: ProtoType }
185
- Curl. with_handle (easy_handle (maxage, keepalive, negotiation, revocation, request_timeout)) do easy
235
+ Curl. with_handle (easy_handle (curlshare, maxage, keepalive, negotiation, revocation, request_timeout)) do easy
186
236
# setup the request
187
237
Curl. set_url (easy, url)
188
238
Curl. set_timeout (easy, request_timeout)
0 commit comments