On Mon, Aug 1, 2016 at 12:50 AM, Gustavo Sverzut Barbieri
<barbi...@gmail.com> wrote:
[...]
> /* see http://solettaproject.github.io/docs/c-api/structsol__blob.html
[...]
> struct Eina.Blob {
>     mem: void_ptr;
>     parent: Eina.Blob;
>     size: size;
>     refcount: int;
>     free: Eina_Blob_Free_Cb;
> }

To address some comments from IRC, that's not the real structure we
should go with, maybe it would be @extern, maybe opaque with native
symbols to create these things all defined in C (such as mmap for file
readers, others that adopt a malloc, others that adopt a static-const
and last but not least others that do create "child" or "windows").

Think of this as read-only memory that have references to the parent
and allows slice or windows. And the memory doesn't need to be
allocated with malloc, such as:
 - protocols that use fixed strings can avoid strdup() by using
static-const stuff. No free() is needed;
 - files can be read using mmap, free() is actually munmap()
 - slices of another memory, like a line in an mmap file, no free() to
be called on that memory. But once the slice itself is unloaded, the
mmap must go away if that's the last reference.

Also, this is optional,  but in my other project, Soletta, we found it
saves some memory and could be of use in EFL. We could keep the
pattern currently used that uses a binbuf to copy the given data.

[reordered the email contents to have send() closer]
>     methods {
>         send @virtual_pure {
>             [[Queue data to be sent to remote]]
>             params {
>                 @in data: Eina.Blob; [[data to queue for sending]]
...
>     events {
>         sent: Eina.Blob, error; [[data specified by blob was sent,
>                                  if error != 0, contains errno]]

pseudo code is like:

send(Eina.Blob data) {
    queue.append(ref(data));
    fd.active_set(fd.active_get() | ECORE_FD_WRITE);
}

_on_can_write() {
    first_blob = queue[0]

    /* this can be more optimized by usage of iovec variant with
multiple blobs being sent */
    n = write(fd, first_blob.mem + write_offset, first_blob.size -
write_offset);
    if (n < 0) { notify error; return; }
    write_offset += n;
    if (write_offset < first_blob.size)
       return;

    emit("sent", first_blob, 0); // no error
    write_offset = 0;
    queue.pop();
    if (queue.len > 0)
       return;

    fd.active_set(fd.active_get() & (~ECORE_FD_WRITE));
}



>     events {
>         read @hot: Eina.Binbuf; [[data is available to read,
>                             if consumed use eina_binbuf_remove().]]

the given binbuf is the internal one used for reading.

That is, on construct a new binbuf is created (with either fixed
capacity or grow-able, depending on given options). Data is read
directly to the end of this buffer using recv() and the likes (with
amount of left memory).

Once the the user takes/consumes that memory, he must call
eina_binbuf_remove(buf, 0, read_amount). This automatically free's up
space for future reads.

This also allows peek (read without consuming), like check if there is
a '\n' in there. If there are none, just do not consume anything.

If a fixed capacity buffer is used, then if the limit is reached, the
fd will stop to be watched and a timer/job/animator/whatever is used
to periodically inform the user about data. This should be less
pressure on the main loop than keeping the fd triggering incoming
data. In these scenarios data should be either discarded (call binbuf
reset()) or copied elsewhere (but then why use a fixed buffer? so not
a real use case).

If a growable buffer is used, a minimum free size is enforced before
every call to recv(), this provides a balance between memory
consumption and number of recv() calls to be executed.

Note all of this is nicely hidden inside Ecore_Con (Efl.Net.Socket),
all the user needs to do is to consume data from a binbuf!

------------------------------------------------------------------------------
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to