On Thu, Aug 11, 2016 at 3:05 AM, Carsten Haitzler <ras...@rasterman.com> wrote:
> On Mon, 8 Aug 2016 12:44:06 -0300 Gustavo Sverzut Barbieri 
> <barbi...@gmail.com>
> said:
>
>> On Mon, Aug 8, 2016 at 12:02 PM, Gustavo Sverzut Barbieri
>> <barbi...@gmail.com> wrote:
>> > On Mon, Aug 8, 2016 at 11:20 AM, Tom Hacohen <t...@osg.samsung.com> wrote:
>> >> Why do we need a "sent" event? Shouldn't this just be handled by whoever
>> >> is calling "send" and then check error code or whatever?
>> >
>> > That send is asyncrhonous, it will queue and monitor fd for write,
>> > when select/poll reports that, then it will try to write and report
>> > back.
>> >
>> > Alternatively if we move read to just be notification, then it would
>> > make sense to make write the same, then it will issue a simple write()
>> > and no extra infra around that (thus will change to return ssize_t and
>> > set errno, which can be EAGAIN if socket is non-blocking, or less than
>> > requested amount if not all data can be written). This would move some
>> > logic from the core to outside, making developer's lives bit harder
>> > since they will have to handle memory management for partial writes on
>> > their own.
>>
>> Talking to Tom at IRC, we came with the following approach, which we
>> both like, others please chime in:
>>
>>  - Create an EFL interface for FD/Stream operations (ie:
>> Efl.Interface.Stream): read(), write(), close(), events: read, write,
>> error... Eventually this can be Efl.Loop_Fd, with extra methods added.
>> No wrapper around write()/read()... if you set flags to non-block,
>> then they may return EAGAIN... they may return partial operations
>> (returns < asked)... they may return errors via errno (or we change
>> operation to return errno and use an @inout parameter for size_t). If
>> you set then to block, these operations will block. No internal
>> buffers or queues.
>>
>>  - Efl.Net.Socket implements that interface, basically just provides
>> socket/fd creation. Much simpler! All that is left is manage
>> socket-specific flags, such as Efl.Net.Socket.Tcp will add some
>> properties for TCP_CORK, TCP_NODELAY... (then removing the "flags"
>> bitwise enum in my original proposal)
>>
>>  - A new class Efl.Buffered_Stream that takes an object implementing
>> the new interface (ie: Efl.Net.Socket would), and this one would
>> create the binbuf to handle copies. The purpose is to make easier to
>> the final user. Language bindings may implement this class on their
>> own, so they will be able to queue write() queue with reference to
>> objects using references. This could also come in a different layer,
>> such as returning a Promise.
>>
>>  - This approach makes the core cleaner and simpler, it is also
>> flexible to add different, non-socket fds, such as pipe(2) or read
>> from a real file.
>>
>> If everyone agrees on that proposal, I'll create a new thread with
>> proposals to enhance Efl.Loop_Fd with new methods, then a reviewed
>> Efl.Net.* on top of those.
>
> i dislike this and still think binbuf (strbuf... ?) are the way to go and
> extend that a little as needed for some cases like you describe.

the binbuf will be there, but handled elsewhere in a cleaner and more
generic way:

 - any object can implement Reader/Writer/Closer interfaces

 - Efl.Net.Tcp, Efl.Net.Unix... Efl.Net.Http.Client... all do

 - Efl.File (say something that operates on a real file) also does

 - Efl.Buffer (say something that contains and operates on an
Eina_Binbuf) also does

 - Efl.Io.Copier takes two objects, one implementing Reader and the
other implementing Writer. It will link both and control data
transfer.

This allows us to link Efl.Net.Tcp to Efl.Net.Tcp without dynamic
buffer growing as it would be with binbuf (the Efl.Io.Copier may use a
pre-defined buffer size to operate, like 4096).

The same Efl.Io.Copier may be used to copy two files, or a file to a
Tcp (upload) or tcp to file (download) and so on.

Whenever we introduce something completely different, like a Pipe, all
you need to do is to implement Reader/Writer interfaces, Efl.Io.Copier
will know how to do it for you.

Same for Popen/subprocess (ecore_exe), you can pipe two process (p1 |
p2), or log to a file (p1 > f1)... or file to process (p1 < f1).

See the following code:

  Eo *httpc = eo_add(...HTTP_CLIENT_GET_CLASS, ..address_get("http://e.o";));
  Eo *buf = eo_add(EFL_BUFFER_CLASS);
  Eo *copier = eo_add(EFL_IO_COPIER, ...source_set(httpc),
...destination_set(buf), eo_event_callback_add(EFL_IO_EVENT_DONE,
on_done, ...));
  eo_unref(httpc);
  eo_unref(buf);

  ...
  on_done(void *data, const Eo_Event *ev) {
    Eo *o = efl_io_copier_destination_get(ev->object);
    Eina_Binbuf *binbuf = efl_buffer_binbuf_get(o); // or slice_get()
if we add Eina_Slice
    // operate on binbuffer.... like eina_binbuf_steal()
  }



-- 
Gustavo Sverzut Barbieri
--------------------------------------
Mobile: +55 (16) 99354-9890

------------------------------------------------------------------------------
What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic
patterns at an interface-level. Reveals which users, apps, and protocols are 
consuming the most bandwidth. Provides multi-vendor support for NetFlow, 
J-Flow, sFlow and other flows. Make informed decisions using capacity 
planning reports. http://sdm.link/zohodev2dev
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to