Set the queue length in unix domain socket - Unix

This is a discussion on Set the queue length in unix domain socket - Unix ; Hi all, I'm trying to implement IPC with Unix Domain Sockets. A producer encodes live video frames, and passes them to a consumer through an unix domain socket. The consumer waits on the file descriptor with a select, and when ...

+ Reply to Thread
Results 1 to 5 of 5

Thread: Set the queue length in unix domain socket

  1. Set the queue length in unix domain socket

    Hi all,
    I'm trying to implement IPC with Unix Domain Sockets. A producer
    encodes live video frames, and passes them to a consumer through an
    unix domain socket. The consumer waits on the file descriptor with a
    select, and when the select returns, it reads data from the socket
    (please note I can't change this, because the consumer is a third-
    party library).

    I want my socket to be a SOCK_SEQPACKET, because I want to keep the
    boundaries between the frames, and I want them to arrive in order at
    the other end.

    The producer starts way before the occasional consumer - it's part of
    a server, and just sits there encoding frames and putting them on the
    socket. When the consumer needs them, it checks if there's data with
    select, reads from the socket and uses them.

    The problem is, the producer starts to put frames into the socket
    until it blocks because the socket's queue is full. The consumer then
    randomly starts to read and gets a lot of data to compute, at least
    until it manages to empty the socket queue. This makes the application
    lag and causes other unwanted behaviours that I don't explain because
    they're related to the third party library.

    What I want from my producer is to produce a frame, put it in the
    socket, then produce another and get blocked on the write until the
    first is consumed. I know I can set the maximum buffer size of the
    socket with SO_SNDBUF, but unfortunately the frames are not fixed-
    length.

    What I'd need would be a way to limit the "datagram queue" of the
    socket to one datagram, so that the producer would write the first
    frame, get another and block on the write() until that frame has been
    read by the consumer (removed from the queue). Then, it would complete
    the write, get another live frame and write it into the socket, and so
    on.

    Is it possible to do something like that under Linux and for a single
    UD socket (I don't want to change the value system wide)? If not, how
    would you do it?

    Please note that:

    - I want to use datagram unix domain sockets because they preserve
    boundaries and I can read one frame at a time. I *can't* buffer on the
    other side.
    - Frames are not fixed-length. One frame could be long 19 bytes,
    another 15 Kb or more.
    - I've got to use a socket because I need to pass an file descriptor
    to the library consumer. The library will sit on a select() until
    there's something ready on the socket.
    - No, I can't modify the library or use another (even if it's clearly
    wack).

    Thanks in advance,

    Cristiano.

  2. Re: Set the queue length in unix domain socket

    Cristiano wrote:

    > What I want from my producer is to produce a frame, put it in the
    > socket, then produce another and get blocked on the write until the
    > first is consumed. I know I can set the maximum buffer size of the
    > socket with SO_SNDBUF, but unfortunately the frames are not fixed-
    > length.
    >
    > What I'd need would be a way to limit the "datagram queue" of the
    > socket to one datagram, so that the producer would write the first
    > frame, get another and block on the write() until that frame has been
    > read by the consumer (removed from the queue). Then, it would complete
    > the write, get another live frame and write it into the socket, and so
    > on.
    >
    > Is it possible to do something like that under Linux and for a single
    > UD socket (I don't want to change the value system wide)? If not, how
    > would you do it?


    AFAIU, the system wide knob is /proc/sys/net/unix/max_dgram_qlen

    http://www.linuxinsight.com/proc_sys...gram_qlen.html

    I'm not sure how to achieve the same result on a per-socket basis.

  3. Re: Set the queue length in unix domain socket

    On 11 Mar, 10:17, Noob wrote:
    > Cristiano wrote:
    > > What I want from my producer is to produce a frame, put it in the
    > > socket, then produce another and get blocked on the write until the
    > > first is consumed. I know I can set the maximum buffer size of the
    > > socket with SO_SNDBUF, but unfortunately the frames are not fixed-
    > > length.

    >
    > > What I'd need would be a way to limit the "datagram queue" of the
    > > socket to one datagram, so that the producer would write the first
    > > frame, get another and block on the write() until that frame has been
    > > read by the consumer (removed from the queue). Then, it would complete
    > > the write, get another live frame and write it into the socket, and so
    > > on.

    >
    > > Is it possible to do something like that under Linux and for a single
    > > UD socket (I don't want to change the value system wide)? If not, how
    > > would you do it?

    >
    > AFAIU, the system wide knob is /proc/sys/net/unix/max_dgram_qlen
    >
    > http://www.linuxinsight.com/proc_sys...gram_qlen.html
    >
    > I'm not sure how to achieve the same result on a per-socket basis.


    Alternatively, how to flush the socket's outgoing queue? When my
    thread is stopped it already had the time to enqueue several unwanted
    datagrams on the socket. When I stop it, I'd want it to simply clear
    its outgoing queue so that it restarts with a brand new frame the next
    time it's restarted.

  4. Re: Set the queue length in unix domain socket

    Cristiano wrote:

    > Alternatively, how to flush the socket's outgoing queue? When my
    > thread is stopped it already had the time to enqueue several unwanted
    > datagrams on the socket. When I stop it, I'd want it to simply clear
    > its outgoing queue so that it restarts with a brand new frame the next
    > time it's restarted.


    I've asked this question in the past, and I was told that the sockets
    API does not provide a function to do this.

    So I use (roughly) the following logic.

    void flush_socket(int sock)
    {
    while ( 1 )
    {
    ssize_t res = recv(sock, NULL, 0, MSG_DONTWAIT);
    if (res < 0) break;
    }
    }

    Calling flush_socket() costs one system call per datagram in
    the receive buffer, but nothing is copied.

    Regards.

  5. Re: Set the queue length in unix domain socket

    On 12 Mar, 09:56, Noob wrote:
    > Cristiano wrote:
    > > Alternatively, how to flush the socket's outgoing queue? When my
    > > thread is stopped it already had the time to enqueue several unwanted
    > > datagrams on the socket. When I stop it, I'd want it to simply clear
    > > its outgoing queue so that it restarts with a brand new frame the next
    > > time it's restarted.

    >
    > I've asked this question in the past, and I was told that the sockets
    > API does not provide a function to do this.
    >
    > So I use (roughly) the following logic.
    >
    > void flush_socket(int sock)
    > {
    > while ( 1 )
    > {
    > ssize_t res = recv(sock, NULL, 0, MSG_DONTWAIT);
    > if (res < 0) break;
    > }
    >
    > }
    >
    > Calling flush_socket() costs one system call per datagram in
    > the receive buffer, but nothing is copied.
    >
    > Regards.


    The consumer will have to do this, of course. Seems it could work,
    many thanks.

    Anyway, it's a pity one just can't set the socket queue length on a
    per-socket basis or simply flush its queue

    Regards,

    Cristiano.

+ Reply to Thread