[Libwebsockets] Segfault

"Andy Green (林安廸)" andy at warmcat.com
Tue Jan 29 15:02:33 CET 2013


On 29/01/13 20:46, the mail apparently from Jack Mitchell included:
> On 29/01/13 11:44, "Andy Green (林安廸)" wrote:
>> On 29/01/13 19:31, the mail apparently from Jack Mitchell included:
>>> On 29/01/13 11:20, "Andy Green (林安廸)" wrote:
>>>> On 29/01/13 19:12, the mail apparently from Jack Mitchell included:
>>>>>
>>>>>> No worries, I am wondering if the broadcast and forked service stuff
>>>>>> is leading people down the wrong path at the moment and should get
>>>>>> removed, so it will be interesting to see how you go.
>>>>>>
>>>>>> -Andy
>>>>>
>>>>> Sorry to snip this short but I couldn't cope with all the
>>>>> indentation..
>>>>>
>>>>> I have now implemented a ring buffer but something odd is happening.
>>>>> With 1 page open it performs fine, however when I open an additional
>>>>> page only some of the data makes it through the socket? I check for a
>>>>
>>>> It seems that when you send data to one websocket client, you mark it
>>>> at that time "done" from your ringbuffer?  Actually it's only
>>>> "consumed" when you sent it to everybody who cares.
>>>>
>>>> -Andy
>>>
>>> Should libwebsocket_callback_on_writable_all_protocol() not give me a
>>> callback with a wsi that writes to all the clients of that protocol as I
>>
>> Sort of...
>>
>>> did with broadcast()? Or am I missing something fundamental, where I
>>> need to loop over each wsi and write them individually somehow?
>>
>> No you don't hae to do anything extra about that.
>>
>> The point is that different connections may become writeable at
>> grossly different rates.  Consider one guy is connecting through a 3G
>> phone, his connection may disappear and reappear over several
>> seconds.  He's not going to become writeable (and get that callback
>> with his wsi) while he's in a tunnel or whatever and you already
>> filled his pipe; he's not emptying his pipe at that time. It sounds
>> like you're thinking of these connections as perfect data sinks and
>> they are not at all.
>>
>> Instead what that call is doing is promising to give you a call back
>> for each wsi of that protocol "when they can take some more".  So for
>> the tunnel guy, his callback will come when he has come out of the
>> tunnel and received and acknowledged the first packet in his pipe.
>> Other connections to other peers will of course have been chugging
>> along taking data the whole time.
>>
>> So, you need a policy for how long you will buffer content in your
>> ringbuffer before the remote client won't "catch up" any more if it
>> stopped receiving for a while, and you need to only retire ringbuffer
>> entries that have gone to all consumers you are willing to send to.
>
> Ok, I've got it sorted [1]. The client gets 50ms to respond otherwise
> they miss the data. Is there a way to check if all clients have
> responded, or if all the clients pipes are empty?
>
> [1]
>
> while(1)
>
>        usleep(50000);
>
>        /* Service the websocket here to listen for connection attempts */
>        libwebsocket_service(controlWebSocket, 0);
>
>        for (i = 0; i < NUM_TOTAL_CARDS; i++)
>        {
>
>           if (card[i]->status == CARD_AVAILABLE)
>           {
>
>              libwebsocket_service(card[i]->websocketContext, 0);

Why do you have n contexts?  They should normally all be handled from 
one... each context implies a different listening socket.  There doesn't 
seem any reason to split things up like that.

Isn't it that you want one context, ie, one listening socket, which can 
serve information from any of the FPGAs?

If I were you I would back up and look again at your kernelside support 
before trying to get any more working all the way through, it's showing 
signs of becoming a tangle / muddle at the architectural level because 
the split between what the kernel and userland does is unclear.

What you want is one logical device per FPGA that follows file or socket 
descriptor semantics.  Since you mention you have an ioctl(), I guess 
you might already have a char device for each FPGA.  In that case, you 
can add buffering and poll() support there.  Then, you can service 
everyone in one poll loop using the extpoll scheme shown in the test 
server (and all in one context).  It seems to me if you don't eliminate 
the confusion that's coming from the kernel side not being right you 
won't get a good result.

-Andy




More information about the Libwebsockets mailing list