[libuv][FRC] Replace uv_read_start/stop with uv_read

590 views
Skip to first unread message

Saúl Ibarra Corretgé

unread,
Jun 30, 2014, 3:29:51 AM6/30/14
to li...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

https://gist.github.com/saghul/909502cc7367a25c247a

(please post comments on this email thread, not the gist)

- --
Saúl Ibarra Corretgé
bettercallsaghul.com

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
Comment: Using GnuPG with Icedove - http://www.enigmail.net/

iQIcBAEBAgAGBQJTsRGuAAoJEEEOVVOum8BZZ64QAL683CgedhuZ/DV7F4KYloGE
mi+oTTmpJw2WRAQzQ3OUaOr0RsiyhdvkD2j7xigbzyIYYAYEj71i9eqyKH4OrFn4
JF3rLXROjwBYDmAI8h0uGCiiiCLqM8nlK16N68Oqt07Bo2S13972wujYBAOuklws
XIo5p0vP4Az+mvPImuj83SNCtujqb4Y2rPEUBAIZ0k1HRJUlhNykTNOKctPMOYJJ
33TCgZnY7MDvJGCx7LIIkcOLQUAsmwjUxiI+9sxu+ENlE9LUUqJFMxwr2dx12817
Mt3DKkwCqvUxnsatl5c9UaburCgFhzZn0bjKflk5xebitV7cVSX8QAhIbqK5TdgF
zzRgxiqzG2najrkwMQ4xXwuy49hdYH6wH+UiP+j4EnE5Si3KBx7ByPDN+Yhlp5/g
mHffiIlEDWf0VQN69mQHhwPDydSTHXrgSv2qkUKtAUaVEVYaiV1vJaxi2VslaPKc
ScaNxW0miMUPaRqiFpTS2MDuL64duD0u0dFB3GV8Gpaoe85ZsSC71ntFmLWBCiFp
TVmjIucSbplsGUoGemLo8Y58HsT695B4QyPe4/EpjV5td+Le1CPdZSPObX1De9n7
g/UYVmzvEe6OdHuBTEyd/OVQ3PNFGmR+J6rQ9+K8KvIyW0eWmBtLfqa1u5DJ3R00
9iwmwR18MZbSDz1e5Q0D
=2Wuc
-----END PGP SIGNATURE-----

Fedor Indutny

unread,
Jun 30, 2014, 3:57:06 AM6/30/14
to li...@googlegroups.com
+1 from me.



--
You received this message because you are subscribed to the Google Groups "libuv" group.
To unsubscribe from this group and stop receiving emails from it, send an email to libuv+un...@googlegroups.com.
To post to this group, send email to li...@googlegroups.com.
Visit this group at http://groups.google.com/group/libuv.
For more options, visit https://groups.google.com/d/optout.

Iñaki Baz Castillo

unread,
Jun 30, 2014, 3:57:29 AM6/30/14
to li...@googlegroups.com
2014-06-30 9:28 GMT+02:00 Saúl Ibarra Corretgé <sag...@gmail.com>:
> https://gist.github.com/saghul/909502cc7367a25c247a
>
> (please post comments on this email thread, not the gist)


"A push style API can be emulated on top of this pull style API by
having a request active all the time and rearming it after a read is
performed"

Does it mean that for just receiving data "all the time" (as the
current behavior) I should call once uv_read() and then call uv_read()
in the uv_read_cb() ?


--
Iñaki Baz Castillo
<i...@aliax.net>

Fedor Indutny

unread,
Jun 30, 2014, 4:00:56 AM6/30/14
to li...@googlegroups.com
Yes, practically, it is the same. It just removes a lot of the mess with alloc_cb + read_cb invocations.


Iñaki Baz Castillo

unread,
Jun 30, 2014, 4:05:43 AM6/30/14
to li...@googlegroups.com
2014-06-30 10:00 GMT+02:00 Fedor Indutny <fe...@indutny.com>:
> Yes, practically, it is the same. It just removes a lot of the mess with
> alloc_cb + read_cb invocations.

So no suggested_size anymore? That may be nice for streams since the
uv_read_cb would be called again (if rearmed) when received data is
bigger than the provided buffer. But what about UDP?

And BTW: how is it useful to pass many uv_buf_t to uv_read()?

Fedor Indutny

unread,
Jun 30, 2014, 4:11:48 AM6/30/14
to li...@googlegroups.com
Well, it may be useful for some applications like `bud` or node.js TLS implementation.

We have a ring buffer consisting from a multiple sub-buffers, and it could be beneficial to read into all of them at once.


Iñaki Baz Castillo

unread,
Jun 30, 2014, 4:14:17 AM6/30/14
to li...@googlegroups.com
2014-06-30 10:11 GMT+02:00 Fedor Indutny <fe...@indutny.com>:
> Well, it may be useful for some applications like `bud` or node.js TLS
> implementation.
>
> We have a ring buffer consisting from a multiple sub-buffers, and it could
> be beneficial to read into all of them at once.

Clear.

Saúl Ibarra Corretgé

unread,
Jun 30, 2014, 4:21:06 AM6/30/14
to li...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Yes. You could bzero the request and reuse it, use the same buffer,
whatever you want.

- --
Saúl Ibarra Corretgé
bettercallsaghul.com

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
Comment: Using GnuPG with Icedove - http://www.enigmail.net/

iQIcBAEBAgAGBQJTsR2zAAoJEEEOVVOum8BZkUAP/0Pd8wLhZuEWIzhtz0jF+7vS
sJm5Wypn7iNLu+edX/b9IqTd5K5ZQ7ivhUbuQ1UtlYIEHIyzgYnSaJZ3mYApVaug
5G1WPNfoqKHzCnMQcJ88koINH73CeZAWCMybtThsfI8VZwE1lP1bfEYhyo+xL/3d
fzGf6K9AK/S2z0Pe2y6HWckIAd9uD7V8Mea7RgNpaKYakrm8kPhvRIiUYDpjmL9j
XeJF7c7hXK9tLKMXtTk+CYYrwPugVdmYWftg8kcxRjqxzC1xCmOIlAbdmB6V+EUJ
YUQ6hKzM+qUrXvrn2X0ouOAIU5veCTg+dDp75v1cWiMAqqJmyOWWQAVe5jD44EDd
sPWlJZ6mQ4A7HfTTCRBw1u27LYIHwCw/5W/Fm6PPHBS0n53GAwhZYJOook99KMu5
PyRFdvfgOB7OJOtzAPzBedRudW8EKGig1pHCgKZsC9iAYCA78hmw2FNlAJcEWOiw
vqmALUUgjjpWHuud+txj7N5zYj1OqYO54IGgwTOH5bjTDgtQDYRx7dZJUyZv0WH6
rWIAKGVkgzBzwaEz96u33eAzcQ3bQYlpQxpCac9UO5sF6mPNUrWuoHgWy6g8kxdv
v1dSm2qiNa4Y24WyNgoLW6uywVtTJ5fLBQKIHXD+791sx3W2E4suEXcVt8BGbXjn
Trmo//EyOaSap5kFhQgx
=a/Yb
-----END PGP SIGNATURE-----

Iñaki Baz Castillo

unread,
Jun 30, 2014, 4:24:11 AM6/30/14
to li...@googlegroups.com
2014-06-30 10:20 GMT+02:00 Saúl Ibarra Corretgé <sag...@gmail.com>:
> Yes. You could bzero the request and reuse it, use the same buffer,
> whatever you want.


What is "bzero" the request?

Fedor Indutny

unread,
Jun 30, 2014, 4:27:10 AM6/30/14
to li...@googlegroups.com
I think it is: memset(req, 0, sizeof(*req))


Saúl Ibarra Corretgé

unread,
Jun 30, 2014, 4:36:16 AM6/30/14
to li...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 06/30/2014 10:26 AM, Fedor Indutny wrote:
> I think it is: memset(req, 0, sizeof(*req))
>

Yep.

- --
Saúl Ibarra Corretgé
bettercallsaghul.com

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
Comment: Using GnuPG with Icedove - http://www.enigmail.net/

iQIcBAEBAgAGBQJTsSFAAAoJEEEOVVOum8BZt8AP+gNaqqMWv6TN5HLvy4ipN94X
F6omvofhlKWo89Jlu4p0uDJkrAFud3ytOnJr9gLjtr98+2ONZwfmTfhCg4be+vcY
5a0b9ZkaN/ZirTNWhbKQ2xFqK4pkVCL0s4x9JzHpPCmcgKenq1IUxkHk9bSqqgOY
CYXs41zGLAUBc5ZjRcYLFGuZoTaMs4EIwNJ0N4csHvbHzXgiOzXUiz8chhril12X
V43Q0dFdOrAXbv8rl7JUdmUeQ06eQm/YrsfJFBnIeC2FaxrbS3BpcaL+/0G/e9ZX
GWbZ7aZ0PnsDo9JT5PO9ES432hedKpIwh1KJnzipXFaRELQFG6ts4s+2xUAyFxgS
MRYOnphtYkW4tqmNgQGUrByWf46U8sbnfUohsqwvdeObU6OMfAtn5JcwkZkFCfdh
ZjfRn1IKV/UH20tv7wk2g8n/4cS0zwB0XCeZHW/7zi8uVjlNnfFO1phcaOHHiHBA
IIhgCjIoIhMWzsYdc1y1k8keWou+SAA3OnqV4bCKqAcOwc5xlT5WPvY3M6lb+eZW
3cVKImb4t+wiuniki21UzASG8ZQak5Kt+AO4IdnJr2J9Cc7UnrVoR67OGPLhOxlm
sGKuKrZSjpOS9hPC7AA0cxscPc4TeK3T6O7zQXqGlQtqb5GVFHyXMOM8DZEX46K9
1z/DG9+ubWXdb0kuJpy/
=zbZ7
-----END PGP SIGNATURE-----

Saúl Ibarra Corretgé

unread,
Jun 30, 2014, 4:37:10 AM6/30/14
to li...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 06/30/2014 10:23 AM, Iñaki Baz Castillo wrote:
> 2014-06-30 10:20 GMT+02:00 Saúl Ibarra Corretgé
> <sag...@gmail.com>:
>> Yes. You could bzero the request and reuse it, use the same
>> buffer, whatever you want.
>
>
> What is "bzero" the request?
>
>
http://lmgtfy.com/?q=bzero

- --
Saúl Ibarra Corretgé
bettercallsaghul.com

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
Comment: Using GnuPG with Icedove - http://www.enigmail.net/

iQIcBAEBAgAGBQJTsSF2AAoJEEEOVVOum8BZtCMQAJ9kfDsjh+hYDab78Qr1McxZ
OjGkjjgQjvAmt0swSuhs3JWrI46vcm3Br8tSV+pU4aVUhgKtlPdav1FZr/Th9uIO
UuLsNjviglgy8CKEWDikw1Ljk1lhWHrBL9WawA/MI0XMAGDTGxWSj5ws8NcwfJim
U564ysltvU3JeNAOvrpKsDwWs8sFjeKlLdjx6qInPs7pG5NHW+u8NlPEDOzUI4XJ
C71jo0SGwj/KfodbCqgxxh9N/XUrC+r/XPXY3SjsB8LeukzHpWcLHIcoN60GrWeu
lATDlogCswnNPMhQ+IIuSd9JwvwFBoZl77dKMwV6UEe5lNilewji6VzSzu4Kf99a
SiB3k+urkq8PD9t1jbOTK3Ni6kRYkonPlL7EbbvcUXrLiirTUTf+GbH8snYJzAlI
UkVCR94SvYGl2WBR71TstwwyHoKF0bZH3M5qQ6pRnCnoO40sguULxRV/9OPEJdeh
yW3FWeMhv7PKc+nXUOXhhkWH2IgqNU+pOeT1PKVjjWP042zpmqnitNmwbuM2l8Qx
Ie7agIxvBbN3ZN4KE5qN7u0oHOgkPkrIWP1I4OEfMYHf7sptud5+/pn3sMx5FFbj
5H+byYoOWrncADE1z1uMhc5iYDpuopMRZUInaTsJDmMfl61rClghzjVlU33rGWac
1ZCSlKFkFtGZqiUDkTkA
=G/K1
-----END PGP SIGNATURE-----

Ben Noordhuis

unread,
Jun 30, 2014, 5:42:10 AM6/30/14
to li...@googlegroups.com
On Mon, Jun 30, 2014 at 9:28 AM, Saúl Ibarra Corretgé <sag...@gmail.com> wrote:
> https://gist.github.com/saghul/909502cc7367a25c247a

A hearty +1 from me but let me point out that the suggested function
prototype of uv_read() requires that the memory is committed upfront,
bump pointer allocation/release around the actual read won't work.
Adding a second uv_read() function that takes an uv_alloc_cb would
make that use case possible again.

On the other hand, not many libuv users seem to do bump pointer / slab
allocation. Node.js may have been the only one and it no longer does.

You could take a reactionary approach and not do anything until
someone complains. It should be fairly trivial to add later on, by
implementing `uv_read(uv_buf_t* bufs)` in terms of
`uv_read_alloc(uv_alloc_cb alloc_cb)`. Just make sure you leave some
room in the uv_read_t for future additions.

Fedor Indutny

unread,
Jun 30, 2014, 5:52:45 AM6/30/14
to li...@googlegroups.com
Ben,

How does it break bump allocation? You just bump the pointer and give the old value to uv_read(), right?

The proposed API is technically *identical* to the old one.


Ben Noordhuis

unread,
Jun 30, 2014, 8:09:53 AM6/30/14
to li...@googlegroups.com
On Mon, Jun 30, 2014 at 11:52 AM, Fedor Indutny <fe...@indutny.com> wrote:
> How does it break bump allocation? You just bump the pointer and give the
> old value to uv_read(), right?

With uv_read_start(), the alloc_cb usually gets called right before
the read_cb. You can (ab)use that fact to implement a slab allocator,
where you return a large slice in your alloc_cb, then shrink it to fit
in your read_cb. In pseudo-code:

def alloc_cb():
buf = slab.used
slab.used += 65536
return buf

def read_cb(buf, nread):
slab.used -= len(buf) - nread

With the proposed uv_read(), you have to commit the memory upfront.
That makes a slab allocator much less effective because concurrent
read requests will fragment the slab.

Fedor Indutny

unread,
Jun 30, 2014, 8:11:48 AM6/30/14
to li...@googlegroups.com
Again, it is exactly the same :) But gives you more control of the situation.

You just give it the chunk and shrink the stuff in a callback of uv_read(), you just need to call alloc_cb yourself, this is the only thing that has changed.


Saúl Ibarra Corretgé

unread,
Jun 30, 2014, 8:29:35 AM6/30/14
to li...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 06/30/2014 02:11 PM, Fedor Indutny wrote:
> Again, it is exactly the same :) But gives you more control of the
> situation.
>
> You just give it the chunk and shrink the stuff in a callback of
> uv_read(), you just need to call alloc_cb yourself, this is the
> only thing that has changed.
>

Well, there is no alloc_cb in uv_read.

Anyway, why would one do concurrent reads? As Ben suggested earlier,
we can leave that out for now, and address it later if need arises.

- --
Saúl Ibarra Corretgé
bettercallsaghul.com

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
Comment: Using GnuPG with Icedove - http://www.enigmail.net/

iQIcBAEBAgAGBQJTsVfsAAoJEEEOVVOum8BZB10P/iHXudWgv+ag8PYAJtghZ/2+
Lwp4BsqIBxpgzR+eCuRGqiyXmN/tPvfeN01u1J+cFnFgR8F0XvonCDAgHHr6AiJd
slbGJlfFURojDtPTZKxT97ZG8Qzd9m9uEc8Fo7vGFJWKfMt6SgACo83bN6fpwd32
HSrMaYgkJE14LjV8YKTM2dcObAu7MNmr7+Eer1zDAzkmv1zh9AciOj72biaJjsLL
UVWX/X8Gbe4GYkrn56Ik1SUnU40iUDiBXqTx+sXrh/z3wan1rxvaZ2osdY22u5K1
dlZwRJDy0PAY2vonWacypkSout616JhMJ2bfpW8BX18etuOuxoNFN8H6JUhvawll
qYWoCax+y/U9dKlTjO/WT1RXcEVYFuqL3LSOa7GD3Yhu4IRnFWHT6U0RZd+Ubybm
oI50F6X0EY+68o578XGsRIOV7NYB4OkeeXaZFLrBODgDj6VcaYRoCwZ6g2j9bgDG
dijHZ8aUFPuLdW8uHNp23krBw6zG1Ns2lPPFBbYROQHYrPPIohsS2BrYs830tbvH
7BZCQHg6+VngczpzkQdqn68i8DXJUqh8dv0YN8s8uHKqxIyahk96T6Owt8Q5vX3D
K5Z4SccuXtfD2Br2e3A2f4fH092by8EZoY/AIicisksaNqjUfYEFL3pJJlOqHiP9
ED08KeUCkwSv5YpItdYS
=Kp1b
-----END PGP SIGNATURE-----

Andrius Bentkus

unread,
Jun 30, 2014, 8:53:05 AM6/30/14
to li...@googlegroups.com
Well, there is no alloc_cb in uv_read.

alloc_cb allows for libuv to eventually call IOCTL(FIONREAD) to check exactly how much there is to read.

This api wouldn't allow this possibility. Currently the implementation uses just 64k so it doesn't matter I guess.

Saúl Ibarra Corretgé

unread,
Jun 30, 2014, 9:09:52 AM6/30/14
to li...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Are you currently relying on that (use of alloc_cb)?

- --
Saúl Ibarra Corretgé
bettercallsaghul.com

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
Comment: Using GnuPG with Icedove - http://www.enigmail.net/

iQIcBAEBAgAGBQJTsWFgAAoJEEEOVVOum8BZnCQP/RNfHyIUXe8iy8xRZMh8GcRl
m6zwhmxRg9BsxRWyzHufHtkDmIw1OGoD5+MKYNam8Ww96K6kD/wzJGdDnqu64MNs
wMEV5DES8UUxtMNc2l2QcvVsPmWtFEIe5znFCfKznPADyepMuBMzkiL22eOtDWrC
jj4jq/Fze462zlzGd4XBijYTCY4/N0vF2jqi49ezPcHqCABC/QugwLrY+P0ezswu
UPCK2OFnzow821g2q2CQp0OlYrhHUzIW3hby20LeH/MWjlQBcQD6wlSVxKcEDNLU
C8MIiM9sVGgQ5yys3wDLh8Rut6kqUdBE/Ee5tYE1tRd7vvjgQTdnbhCJ9ImAjFHv
OiwjQSXetQQ0ODDBbmT5CH+ZZJ0fqbZUBfaiZR0K+l7NbbOWDmdMGptxpPW6V8zn
vcKPzWG7Tb8v4fuXwEPtB/5gkpSnVqvuEwylCZVnttszxaTIqpkX545W2EuY3aGR
g6xv7pzVSmOTaAo3gLqAni9SE3UgUOMgimkho0rDEz17VyTY9E8oZERBiHypI3Tk
JkL0uW1OhfgR8bjL5vjYBw+0mNf0P7x94hpVCoY8ROyTA/ckRQTBk2vd8FOpTAAK
BEhabS1xMfvaKLQ6VaAGmbSeLJXL7Cy0OvC5wONTBbDTeKZindWHAtt+HtOgmTM9
4RddbjrxzV2mhRj+nlce
=vVG/
-----END PGP SIGNATURE-----

Andrius Bentkus

unread,
Jun 30, 2014, 9:20:20 AM6/30/14
to li...@googlegroups.com
I guess we can add a uv_suggest_buffer_size(handle) which then invokes IOCTL(FIONREAD) on unix and does whatever windows supports.

This is actually better because now the user can decide when he wants to do a system call like that(sys calls might be expensive).

Saúl Ibarra Corretgé

unread,
Jun 30, 2014, 9:27:57 AM6/30/14
to li...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Where do you want to add that? Ben tested that and it was too
expensive. AFAIK doing the FIONREAD would be useless if the socket is
not readable, and you don't know that because that's the whole point
of uv_read: "I want to read X data, give it to me when available".

Without thinking much about it, I'd say that it could be done with
another function, like uv_read, but taking a alloc_cb instead of a
list of buffers and a count:

UV_EXTERN int uv_bacon(uv_read_t* req,
uv_stream_t* handle,
uv_alloc_cb alloc_cb,
uv_read_cb read_cb);


- --
Saúl Ibarra Corretgé
bettercallsaghul.com

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
Comment: Using GnuPG with Icedove - http://www.enigmail.net/

iQIcBAEBAgAGBQJTsWWeAAoJEEEOVVOum8BZ9YIP/1a85fFV5WwmuqwmGIiD32Ho
FD54kCEONWUDz+KxqyuWNJJcW5kRXZruXRoPdq/wqU3yiZL65FuhCNabUeEcrl3s
ElJ+VShtT6/mDbZKWlm4g7Hl5NUo6H6FmfExFfbLZtpyZetBkjzj26gKXMSIP1cZ
6z+op1mpseYeaISUlHVBOduspqNUItc8sYy4ik6egNbRrfAH9OLskn0s0ld7X2Ts
7G3WphlJjyk+BNOn/EaK9YS0FuTcpveQFQIrikhG1C/Rb4quib1VZ53zPIbzqVsQ
9zQXGXPXu8Zh0aCH6QMviIZ815kO0QVwyOfVmgyWb5p0AS4liRUQwzdcFZ0H0HR8
0CylIQELJIqXUyLDHQXK/d5L2R7a8O/zH4r+SrsaIeF758s9oeNxSG6dNKHX+mYv
4+IxsP83LrqVbjpKAqCYar3lFBdWKQvGqDoh7vUi+Yet8v6zvUwi2Nqd7ZFpenzN
Tl2FJiUieRNaXmeMxKezigZluLzB0iRM/gVtbpSJQMJEwz360KY0KOMT2BWzWqb1
IbZJXN92Ibs3mUYqW28oMXQ78mokrvjkGCkSmM0+e0mrptA4+60yIu5LObdJqI0h
wcnNHyl7m7r7EOoEA4rGEcUkjAF5etoKUy3sGNHMDq0hj4gU76LVyh0Onl+kuv0o
NADOxA1AXoQ/q7AW1A4F
=sOG4
-----END PGP SIGNATURE-----

Andrius Bentkus

unread,
Jun 30, 2014, 10:00:02 AM6/30/14
to li...@googlegroups.com
Where do you want to add that? Ben tested that and it was too
expensive. AFAIK doing the FIONREAD would be useless if the socket is
not readable, and you don't know that because that's the whole point
of uv_read: "I want to read X data, give it to me when available".

You are right.

I have actually tested it being faster with when the connection is fully saturated. ioctl(FIONREAD) returns 6 times the value of 64k and that made it faster then the 64k suggestion.

But now that I think about it: if we just provide a buffer that big without FIONREAD then we should be even faster.

Only reason why one would use FIONREAD is to create buffers of the exact size. But creating just a big buffer for the entire loop and then copying the from it into appropriate sized buffers should be faster anyway2.

Yeah, I'm convinced that ioctl(FIONREAD) is useless and in your proposed API doesn't even make sense.

bertb...@gmail.com

unread,
Jun 30, 2014, 10:13:57 AM6/30/14
to li...@googlegroups.com
I am 100% in favor of switching to asynchronous read instead of read_start. However I think you want to stick with alloc_cb unless you can think of something better.

Imagine you have 10k open tcp connections that all *may* receive data. Then you are pre-allocating 64k * 10k = 640mb of buffers alone, which are almost never used.
With alloc_cb, libuv can ask the embedder to allocate memory as late as possible. For TCP handles buffers can be allocated very much "last minute", while for operations that happen in the thread pool the buffer can be allocated upfront.

- Bert

Iñaki Baz Castillo

unread,
Jun 30, 2014, 10:15:39 AM6/30/14
to li...@googlegroups.com
2014-06-30 16:13 GMT+02:00 bertb...@gmail.com <bertb...@gmail.com>:
> Imagine you have 10k open tcp connections that all *may* receive data. Then you are pre-allocating 64k * 10k = 640mb of buffers alone, which are almost never used.

+1

Fedor Indutny

unread,
Jun 30, 2014, 10:17:02 AM6/30/14
to li...@googlegroups.com
We could expose this value with another API method.
--

Saúl Ibarra Corretgé

unread,
Jun 30, 2014, 10:31:11 AM6/30/14
to li...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 06/30/2014 04:13 PM, bertb...@gmail.com wrote:
> I am 100% in favor of switching to asynchronous read instead of
> read_start. However I think you want to stick with alloc_cb unless
> you can think of something better.
>
> Imagine you have 10k open tcp connections that all *may* receive
> data. Then you are pre-allocating 64k * 10k = 640mb of buffers
> alone, which are almost never used. With alloc_cb, libuv can ask
> the embedder to allocate memory as late as possible. For TCP
> handles buffers can be allocated very much "last minute", while for
> operations that happen in the thread pool the buffer can be
> allocated upfront.
>

Ah, you are so right! I proposed this update on another email:

UV_EXTERN int uv_read(uv_read_t* req,
uv_stream_t* handle,
uv_alloc_cb alloc_cb,
uv_read_cb read_cb);

This would actually make it more flexible, I think: those who want to
allocate it upfront can embed the req in another structure and attach
their preallocated buffers there and then use them in alloc_cb.

PS: I need to give this 2nd version a bit more thought, I wrote it
while multitasking so I might be missing something.

- --
Saúl Ibarra Corretgé
bettercallsaghul.com

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
Comment: Using GnuPG with Icedove - http://www.enigmail.net/

iQIcBAEBAgAGBQJTsXRvAAoJEEEOVVOum8BZf/oQALkyiicsZREXSXuehVTQ/gTk
QGT0bE3DZ407P3+KVyC66KR2rqY6k4yC0ScMeeP+zMbZRFEnz+O3k6ZnE7FAUnzk
eCGrGq5LNN+K+yq1oiXeQDh4eJiXNdQHHa0lNEXLdZ/nUpYOXfcB1om4TYfHm7kB
9kKGQOHwn2FMSSEr/uRXv0m31DTWNHYhbvyxciVzZ51ewRm7IHB3XXBpjMDYgj7U
NcJIwWLNZPyXPqzInXu6837wbUojmA9iMHuCSwLIsbVIsYeajgaPvG6H7O3yItSQ
mMWPzXRx1gnX44476yZgwNte7UE+lD4qfsGHEK/KcIzKW7ysV2uHs/cguzCAdo79
qRW8noOFZJryK7+Z9Fv9FqV52FmprKFkpVVQ3RdN/Qka+mg0MRqHECOtoQ9OlNMt
P2XSp5Z8rXeZVc/0KaoxWuqF4cWnNvbTGQdZ7ex8fg+CbN2bI4Zu4UEPWBuh/eDn
fDMuE3jTCtRtoXAW5cu/NxjxupJgELhsQIK/uvJE5oRnVHINgrSInuK9gJVoOgtF
86U2pMbXSYOWYhLe9B4L4PA2871pW+XnFxcro+lVBYPVwlzV33lL3h/eDXR29dVq
rrOc4QDtvxAEytvAfFndloEXPB7lwkBvhB3nD12amO0bieAOnCdLdw9VR4Q8oud/
kdFMogn/pe2cc2gIJrXG
=C+8A
-----END PGP SIGNATURE-----

Fedor Indutny

unread,
Jun 30, 2014, 10:45:59 AM6/30/14
to li...@googlegroups.com
This won't allow us to pass multiple uv_buf_t :(

But yeah, requestify all the things!


-----END PGP SIGNATURE-----

Andrius Bentkus

unread,
Jun 30, 2014, 3:41:21 PM6/30/14
to li...@googlegroups.com
Does windows delay the allocation of a read to the last possible moment as well?

Saúl Ibarra Corretgé

unread,
Jun 30, 2014, 3:56:19 PM6/30/14
to li...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 06/30/2014 09:41 PM, Andrius Bentkus wrote:
> Does windows delay the allocation of a read to the last possible
> moment as well?
>

AFAIS yes. There is some code that preallocates the buffer for X
connections, but it was "tempmanently" disabled in 2011:
https://github.com/joyent/libuv/commit/4e9edceb980401d92d45710a07b00872b430fd12

Not sure why this
(https://github.com/joyent/libuv/blob/master/src/win/tcp.c#L455)
zero-read is needed, maybe Bert can elaborate.


- --
Saúl Ibarra Corretgé
bettercallsaghul.com

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
Comment: Using GnuPG with Icedove - http://www.enigmail.net/

iQIcBAEBAgAGBQJTscCjAAoJEEEOVVOum8BZgo4P/RDo64V34nP9OE4iGnmxDu7A
Ovm+4rQQNtAK+2mOO5wHlKasNwskzUZQ5U3Kwm+2KoNgOK4FQQBc1lojbKtTmt6G
ZIY+N3frk17UOQgUBKue7IJl6SZ5etI0I7Be64DqpMY+6745eg7mmxLW05NOnBM2
kMkWvMi8OxiVqlzcqOrnsRGm9s4LAwOtRVsPM6AT9/lnlZ6t3IEvwM53c9+xryY2
gO6vFo1PqaR8wFCiy071ZwJaVoy4jaypsd2GDApM5Co30F1p88EGY7qrcwXzPV+L
18A6vyF0WYxLoCGUYZAvnijnS45Ym//LRY1D9Afe1bpo79R15nk+3XXXw7qXYx+w
tmdHbhuvAetciwuKDW48x+iKF9VYvBSxkk/WPF3vtFaSlNSpYKRx8FXPw3E2Xvt/
6w3M9TwEMjqK+bJrmw9vJy7UNvd2Gnz8wacdEVzwniKuVLzYKLGaM1BLS2ov9Ajx
Xp6C8VIU4fGLZo3CVT4VGiIdsoLqS99h3ws0+MkYPkMhuplTjTtzPqg3Y+KHAtsS
aBXl2FNDSNescM0aPRd08k/Y4j+qZToVQEYMN9eCzxvrVI68XL+DyFea729bJS46
SlZkbYcHoa8iPopK+HWOwZIVEf9o9msqfME8OSInT5aBAgq2uDuyJ/OuSR4Znw+L
4t0FNvH6YE6IPDBHgh9X
=KhcQ
-----END PGP SIGNATURE-----

Iñaki Baz Castillo

unread,
Jun 30, 2014, 6:17:54 PM6/30/14
to li...@googlegroups.com
2014-06-30 9:28 GMT+02:00 Saúl Ibarra Corretgé <sag...@gmail.com>:
> https://gist.github.com/saghul/909502cc7367a25c247a
>
> (please post comments on this email thread, not the gist)

I like the proposed API, but just a question: why to "imitate" the
write API? this is, "write" is something that the user decides when to
do, but "read" happens when the remote peer decides it.

Why this new concept of "decide when to receive"?

Really, I like the API.

Saúl Ibarra Corretgé

unread,
Jun 30, 2014, 7:49:55 PM6/30/14
to li...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

For one, it's analogous to the synchronous counterpart (read / write),
but most importantly, the old API can be easily emulated with this
one, while the other way around is quite cumbersome. Also, this
concept of requests that complete in the future makes a lot of sense
to me, and others apparently :-)

- --
Saúl Ibarra Corretgé
bettercallsaghul.com

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
Comment: Using GnuPG with Icedove - http://www.enigmail.net/

iQIcBAEBAgAGBQJTsfdkAAoJEEEOVVOum8BZcM8P/0uJR9wy34XWx+7lQsS+3xbP
Kw+PZlq2TmThzk+QetPl1MEle2F4Mg38AJR8m2ngficifSOKBM9PjRwGn4PmrjyK
DNiehHXWRj0r04PqAerEb9x6qxqYG+PQcFj+fAaLBYpGyBmR3IpywywdvIFnBLQq
NfCHxasZENK/8EgBZIVwj61VgdCywCx+WkhwpG19cu7eJonZKEm77yjL8W4UefIA
zmLds327aM6lNiR+ahQxzgCvWC+V73QJVoEdNhZ1ZZStDkINcJnNCnZk63iDbsCO
r3xDKxhUcum/ZVowiKjbxVexvymhntULajI26U8ItDHcBgDrQ1Lt6ObX0ceiI8wK
ARyF1Q6X0YdblxJCdZlmJ1YqHlAVn4Kh90DL/W6UwBZreRjTg2EXbK7Td2fXpIbw
7kgT9rtXsppithLigjUbQmRZwHN0TXO8bzDDHAdmO7a0mTAxbIb/cyuuyFqyRvKU
t9Faltx1IsdUUm3qmutvNlQTgfBKQlqCdybVWs8282+130WGp257NSDYrFCboKtm
3Dyo0saugY9D7MxEQ4z51GFkZtgyqK3rFZm4n/HsHVIiLzPZCe6zNWNC5QHTY1Xg
0czq8XeC06W4PayRhWFvyfsvaHMyb3iox5S62XGCKOJdHDdL6Aq423DD+ePoeBDb
ThhtvZsnjaj2ghOHYLzE
=cuxj
-----END PGP SIGNATURE-----

Saúl Ibarra Corretgé

unread,
Jul 1, 2014, 4:28:00 AM7/1/14
to li...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 06/30/2014 09:28 AM, Saúl Ibarra Corretgé wrote:
> https://gist.github.com/saghul/909502cc7367a25c247a
>
> (please post comments on this email thread, not the gist)
>

Updated proposal:
https://gist.github.com/saghul/909502cc7367a25c247a#file-uv_read2-md

Basically I ditched the upfront allocation approach and switched to
using an allocation callback. It's still possible for users to
preallocate buffers by using a struct that embeds the request and
storing them there anyway.

Thanks a lot for all the feedback!

- --
Saúl Ibarra Corretgé
bettercallsaghul.com

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
Comment: Using GnuPG with Icedove - http://www.enigmail.net/

iQIcBAEBAgAGBQJTsnDRAAoJEEEOVVOum8BZzYoP/2yhxB7+FprwjLejk/95TrVG
LWXBYCr32vaEi8lWvc/fpyIL42SARtYA3PXsPxqEyRaUAmIghKj2BD6ifwjzYLo+
afGnazEaoTp1jcOVlBBC14otmrIp8xaVCHXNkp2D5B1nJg8OdQUhQATvuC6yTnVs
PelUU5Ve2XZ6dQuMyRdpqKW6qBoaoQakONf3gs0IXBTJB0qLj0ObTNLhrR0WAka+
QXTOM5XR+xopPVwRSGln5/M5bFZev+680cOge69gk8MCqY6eGbO81jyfiIUygAjA
C2Ofd9JoxMEnK3sRhkidk3OvXotYycUSOH6Bhvztv8GFMIDk7RZMXOsUwW32kmAA
RNJvGrmzIeR5Cmds9DZWUl3hRdmiHgkt17jXzyI59ZRdCiSLi0QMBmXnfXpk0OWW
QNg1G+Lyz11DNns0BukROy4HkRCugU5t7ioVeLktv8ulME3Yj1AOkknsZbb9nCH/
IzwebrhoUbwNLpqlH+tlI2zZxya681sSIxsf0m50aK66dm6Q+2whQ49stad30i+b
fpdAtAoTomNIyzoxppP30fLM/GcMdm7TCWRN8OLpyrL6Xw+27zH4P6Co98r9SV00
Ol20tCj1d3NwalxFDrr/q5c0gGIEMb4TeSVPGc2RYvEXATwpT2dBTFT9ncnMDpPl
+g5JE27BTF3pTnYMhKJL
=cbMx
-----END PGP SIGNATURE-----

Iñaki Baz Castillo

unread,
Jul 1, 2014, 4:47:55 AM7/1/14
to li...@googlegroups.com
2014-07-01 10:26 GMT+02:00 Saúl Ibarra Corretgé <sag...@gmail.com>:
> Updated proposal:
> https://gist.github.com/saghul/909502cc7367a25c247a#file-uv_read2-md
>
> Basically I ditched the upfront allocation approach and switched to
> using an allocation callback. It's still possible for users to
> preallocate buffers by using a struct that embeds the request and
> storing them there anyway.

What would happen if I called uv_read() at the same time for the same
stream and/or the same read req?

Saúl Ibarra Corretgé

unread,
Jul 1, 2014, 4:56:00 AM7/1/14
to li...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

You can call uv_read more than once, but you cannot reuse the
uv_read_t request while it has not ended, just like with any other
type of request.

- --
Saúl Ibarra Corretgé
bettercallsaghul.com

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
Comment: Using GnuPG with Icedove - http://www.enigmail.net/

iQIcBAEBAgAGBQJTsndhAAoJEEEOVVOum8BZ1WcQAMFK3Cxg8lc01fqED4ERqNTK
+RNOMR6pMrdn3zcL61NFtsLDMF2IPHpqRqu/mfVQ94WhSf4UZ8PV5SagsUrs+vcV
Lg4onHdZjHOEtdGxh5AILZAPII1z+ASX+ijpM/I/Z7PKvBU8y9SWT1aL4CjtprCe
5LG2J0F3dqgyXu/1SFo8WeoQPndNczITjAhBaLyK5CnTp7AxDQ72l9Mfm+11wf6l
oA+lSM5ja7BeyfSKA8LdEExMaqxXfH1JLooua0omn3dIjXwv34ellEpU3oTjAxtO
lZ8AETCLvjYZeETU4vktV8fdA8sBKuV+neMya8AMNZMz5U6+QpiL90TMHOZ5UMH5
2qWNWe38vkzGADDbSqXCDGWb25mRB22ibxoBwCiE6Tz1tol6ToZyCL1eYJxqv0qf
DROL4JABvKrJGfQtCTQRj5zgxlQzb32Q3Vxdz3h3fK7nrkXxp74zyZXiGkKP2R6A
2DG8h8f6BotuYgWdWO17+ih+AlCNqWgHBpTTJACKKG9TSM4WZn8taSw0OpNnNtYH
ZzjPMwYNMia3rS2jv9zjy4yKDt8vOaEmMJe/vXOtzdKOfxMT1WQCpqZPF4/2Badg
f0B2ZcaYWGbwty95qg6yYIqyJLYcNmEDWYq1pAEpAXXnDO5DCTw9dcmN4tAyVD96
45aAucMahSEa2rvae3Kp
=g2uF
-----END PGP SIGNATURE-----

Andrius Bentkus

unread,
Jul 1, 2014, 5:10:11 AM7/1/14
to li...@googlegroups.com
What would happen if I called uv_read() at the same time for the same
stream and/or the same read req?

It would queue it? 

Saúl Ibarra Corretgé

unread,
Jul 1, 2014, 5:13:02 AM7/1/14
to li...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Yes.

- --
Saúl Ibarra Corretgé
bettercallsaghul.com

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
Comment: Using GnuPG with Icedove - http://www.enigmail.net/

iQIcBAEBAgAGBQJTsntfAAoJEEEOVVOum8BZ990QAMLov17mydbnz3KvRyKhanhH
YTcnb3utLnv9uPB3jUomdTlMBGh5KQIrlSehdzhoZn0B6xCpz7n6b+2G2siC68Rg
45dC558/g/KwV97tVssB9U5hXYkYcPCZXAyoTzBMqX2ud9D9CwDvZOlRhO6iVNJd
cxeeI52YWAv3ZZiL0pWfcPVJXVVAVtm1DhfdMJwp99GShYzT3/FL8PrtlbGsgjUF
HBmB4OceXhlfXwR40PtGtlOJSONHTCnkg217SCppUA9kQTuPdax0zJf3PXdLncJm
WNQgKmhxkA5V562Cc9ATlqBpbcxNVNYAZVAk33ATvlkzAUg6PAdn8hEkYo2tlWJD
DFk/rJ/yVKLnA+rjrL0WkZ1ME+zzpNlnClsCbPnRLWe+rDfpOhR+tk8ctuxGwI11
7YUjA8GIRAJenhUd3WPEkP4rNGa+KbL9lAyoG8D5bjMms8l4URL2ratdJLMy8EJY
pE6cIlaSZ5yVbmfWPY45bSU/CbIvqpJ049jqjp3HAvrAUMJERkrDoGr/gONOZPUd
XrMyksGwsanN9Ekgg4S3mUcJnV2s6jQs14ee1cM/PsCyrWNB+dki7jDebF3pxLeJ
LKx8Mm5cz36gF/3UgCQTLrQAXmEQ5MXDZ54QtVVRizlDCa3zZXbCJ+3EYWnSSWRY
AtIHgsfOMe5ObeD6hpgX
=Vvbh
-----END PGP SIGNATURE-----

Ben Noordhuis

unread,
Jul 1, 2014, 9:21:00 AM7/1/14
to li...@googlegroups.com
On Mon, Jun 30, 2014 at 9:28 AM, Saúl Ibarra Corretgé <sag...@gmail.com> wrote:
> https://gist.github.com/saghul/909502cc7367a25c247a

Moving the goalposts a little: for consistency, similar changes should
be considered for uv_listen() and uv_udp_recv_start().

uv_udp_recv_start() is the easy one, that could just follow uv_read():

int uv_udp_recv(uv_udp_recv_t* req,
uv_udp_t* handle,
uv_alloc_cb alloc_cb,
uv_udp_recv_cb recv_cb);

Allowing for multiple queued uv_udp_recv_t requests would let libuv
exploit recvmmsg() on newer Linux systems. I've observed that
recvmmsg() isn't unequivocally faster than plain recvmsg() but it's
good to at least have the option.

uv_listen() is more interesting. It takes a callback that in turns
calls uv_accept() to accept the incoming connection. A problem with
the current implementation is that on UNIX platforms, the connection
has already been accept()'d by the time the callback is called;
uv_accept() just packages the socket file descriptor in a uv_stream_t.

It makes it difficult to implement throttling well because there's
always a connection that ends up in limbo until the application starts
calling uv_accept() again. There have been repeated requests for a
uv_listen_stop() function for exactly that reason.

Folding uv_listen() and uv_accept() into a single API function would
resolve that. I'll dub the new function uv_accept() and it would look
something like this:

int uv_accept(uv_accept_t* req,
uv_stream_t* server_handle,
uv_accept_cb accept_cb);

Where uv_accept_cb would look like this:

typedef void (*uv_accept_cb)(uv_stream_t* client_handle, int status);

As long as there are pending accept requests, the listen socket is
polled. When there are none, the socket is removed from the poll set.
Allowing for multiple pending accept requests lets libuv optimize for
systems having a (so far hypothetical) acceptv() system call.

One drawback with the suggested API is that it requires that the
client handle is allocated and initialized upfront, something that
would complicate cleanup for the user on shutdown or error. Another
potential issue is when the user embeds the handle in a larger data
structure that until now had an expectation of always having a fully
initialized handle.

Changing it to defer allocation of the handle until there is a
connection is an option, of course, but it would in turn make other
use cases more complicated: for example, using a stack-allocated
handle would require that the user carries the address of the handle
around until it's needed. Tradeoffs...

Boost.Asio takes the 'commit upfront' approach and I'm leaning towards
that as well, if only because it lowers the cognitive dissonance
between the two projects. Of course, enforcing proper cleanup is
easier in C++ than it is in C.

Last but not least, request-driven accept and receive functionality -
especially when cancellable - should make life a whole lot easier for
the people that implement synchronous green threading on top of
libuv's asynchronous API, like Rust and Julia.

Saúl Ibarra Corretgé

unread,
Jul 1, 2014, 9:42:44 AM7/1/14
to li...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi Ben!

On 07/01/2014 03:20 PM, Ben Noordhuis wrote:
> On Mon, Jun 30, 2014 at 9:28 AM, Saúl Ibarra Corretgé
> <sag...@gmail.com> wrote:
>> https://gist.github.com/saghul/909502cc7367a25c247a
>
> Moving the goalposts a little: for consistency, similar changes
> should be considered for uv_listen() and uv_udp_recv_start().
>

Yep, this was my goal, I just picked a place to start :-)
Well, this would definitely be a problem for me in pyuv. I embed
uv_udp_t in the Python object structure, and I can't possibly have it
upfront (the user may have subclassed it...)

> Changing it to defer allocation of the handle until there is a
> connection is an option, of course, but it would in turn make
> other use cases more complicated: for example, using a
> stack-allocated handle would require that the user carries the
> address of the handle around until it's needed. Tradeoffs...
>
> Boost.Asio takes the 'commit upfront' approach and I'm leaning
> towards that as well, if only because it lowers the cognitive
> dissonance between the two projects. Of course, enforcing proper
> cleanup is easier in C++ than it is in C.
>

Here is one idea that I've had somewhere at the back of my head for a
while: have uv_accept return the fd and push the responsibility of
initializing the handle to the user. AFAIS, the current uv_accept
basically gets the fd and calls uv_*_open with it, so the user may do
that himself. An added benefit is that if someone wants to play with
the fd beofre handling it over to a libuv handle, he can. (context:
https://github.com/saghul/pyuv/issues/157)

Taking this one step further, lets add early socket allocation to the mix:

uv_tcp_init(loop, handle, family) # creates the socket early
uv_tcp_init_socket(loop, handle, fd) # initializes the handle with
the given fd

So, back to uv_accept request:

void accept_cb(uv_accept_t *req, int status)
{
if (status == 0) {
uv_tcp_t *conn = malloc(sizeof *conn);
uv_tcp_init_socket(req->loop, conn, req->socket);
}
}

I haven't looked super-deep, but I think we can achieve the same on
The Other Side (R).

> Last but not least, request-driven accept and receive functionality
> - especially when cancellable - should make life a whole lot easier
> for the people that implement synchronous green threading on top
> of libuv's asynchronous API, like Rust and Julia.
>

Yes! Slowly going on that direction :-)

- --
Saúl Ibarra Corretgé
bettercallsaghul.com

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
Comment: Using GnuPG with Icedove - http://www.enigmail.net/

iQIcBAEBAgAGBQJTsrqVAAoJEEEOVVOum8BZv94P/2mULV+Vi0uTH6fL876wRdxU
JX3w5d+O81aEGW2SCr+iraKaQZHN/5Cjo97O/3otNbpZjUuuMoVXy+5NisgruSS/
VaszaYJcGq7dNz2yWKOPBpPcpsq1myhDBN/t2xehTuvpICrGNrjpkbMNNvxDJkQC
c//VqNKooHgp8p0QlcohROXW52mjb698Tfzlt32ojGece0dU2XVuuJ/xiCAXxxoW
rUt0L+TolJE9TSrfdBtUKY7X6w8F3s26bUSkIOmkemPzzRYRxaJQSBK2B2wPmLJT
hwTm0xpSLmyUJ9ySm8get2XLXLCDCGn9KDsT1bldIE5nLXOOR5agqSHiqYWqD0vy
T07PayJo6dEvPqHLN0HQvRurdyoo3xsSR7OAaLndSIK4z0p0N623w4DITqxxuz+j
SvS4O24m8sXHIjae7or7NTweupQMbghoLw5WOHwxH7gPlevM5132vpTpmotVL6C8
sk+DgRsBV6TL9VS7kVWgBRkZAu7ajExdoQ52wkGHieLT8vmbTM/J/20QO0bCGMEm
YmvoSWsZPDJkj9uC/7R/ThsAL9qgPytEgheqqL+lBnyWelb3UWXzhkPQj75SLKFZ
d6VNc1xbTpbODZsVM2qc0s1XBwQ52HxAQpYPPXfGd2sKBAQ9wATjzOdNHcSWXnJc
wfvze8Rc+3Qh18y9Bps6
=IMNc
-----END PGP SIGNATURE-----

Malcolm Malurka

unread,
Nov 10, 2015, 3:48:00 PM11/10/15
to libuv
Hello!

What happened with this proposal?  I am working in using libuv for another project and the streaming API is awkward to use for what I want.  Specifically, I only want to get a read when I ask for it.

Another possibility: would calling uv_read_stop inside the read_cb give me pull semantics, and work?  Or is there a race condition somewhere?

Thanks!

/Malcolm

Ben Noordhuis

unread,
Nov 13, 2015, 3:00:04 AM11/13/15
to li...@googlegroups.com
On Tue, Nov 10, 2015 at 9:46 PM, Malcolm Malurka <mmat...@gmail.com> wrote:
> Another possibility: would calling uv_read_stop inside the read_cb give me
> pull semantics, and work? Or is there a race condition somewhere?

No, that should work.

Malcolm Matalka

unread,
Nov 13, 2015, 4:32:45 AM11/13/15
to Ben Noordhuis, li...@googlegroups.com
Sorry to be a stickler here, but is that a guarantee or a hope? I don't
know what 'should' means in terms of API semantics.

Thanks,
/Malcolm

Saúl Ibarra Corretgé

unread,
Nov 13, 2015, 7:31:46 AM11/13/15
to li...@googlegroups.com
Hi!

On 10/11/15 21:46, Malcolm Malurka wrote:
> Hello!
>
> What happened with this proposal? I am working in using libuv for
> another project and the streaming API is awkward to use for what I want.
> Specifically, I only want to get a read when I ask for it.
>

I started working on it, but got sidetracked fixing other stuff, and
sadly didn't have the time to continue working on it. I hope that
changes, but alas I have no idea when that will happen.

> Another possibility: would calling uv_read_stop inside the read_cb give
> me pull semantics, and work? Or is there a race condition somewhere?
>

Yes, that's a way to do it.


Regards,

--
Saúl Ibarra Corretgé
http://bettercallsaghul.com

Malcolm Matalka

unread,
Nov 13, 2015, 8:39:02 AM11/13/15
to Saúl Ibarra Corretgé, li...@googlegroups.com
Awesome, thank you Saul and Ben!
Reply all
Reply to author
Forward
0 new messages