Closing a socket.
Joel Sherrill <joel@OARcorp.com>
joel.sherrill at OARcorp.com
Fri May 13 13:13:41 UTC 2005
Chris Johns wrote:
> Joel Sherrill <joel at OARcorp.com> wrote:
>
>>
>> This is the crux of the solution. The returned error status must get
>> back to the blocked thread only using memory that has a lifespan
>> longer tied to the thread. The TCB has a return status code but it is
>> probably
>> used back to the point at which the blocking call.
>>
>
> The hard part is the thread being blocked in the networking code rather
> than just the RTEMS syscall code. If the blocking calls only originated
> in the RTEMS syscall code it would be a lot simpler.
Yes it does appear that there are multiple points where blocking
can occur but don't they all boil down to only a handful of calls
to event_receive?
>> Since it is blocked on an event, the object it is waiting on is not
>> going to disappear with the deletion of the socket. Thus it doesn't
>> get a hint there.
>
>
> Are you saying by using the TCB you are ok as it has not been deleted ?
Yes, exactly. If the thread gets deleted, it doesn't care what the
return status was.
You have to know the thread blocked since you directed the events
at it. If necessary, we could add simple helper call to get and
set the per thread status.
>> My next thought would be that you would have to receive a "socket
>> deleted" event. This would require adding an event to the set
>> used. If you wake up because of the "deleted" event, the task
>> is obligated to return an error without touching the pointer.
>> The rtems_glue.c soconnsleep() and accept() code would have to
>> honor this.
>>
>
> Again the error code is not checked in the networking code so ignored.
There are only 3 calls to soconnsleep()in addition to the accept()
routine. They would just have to be fixed.
Also there are only a handful of event receive calls in the stack
as well.
This shouldn't be a hard thing to do. One approach is to send a
deleted event and let the code after the receive check for that
event. simply avoid touching the socket memory, and return a
"deleted" status. Those calling a blocking helper would have
to put the return status into a local variable and make sure it
was OK to reference malloc'ed memory.
If you don't use the deleted event, then you should be able to return
status through the TCB and just use that. Again if the socket is
deleted, then code has to avoid touching malloc'ed memory.
>>> The rule I use is any thread that makes networking calls deletes itself.
>>>
>>>> --> I believe the rtems syscalls should be changed to make it safe to
>>>> close a socket on which another thread is blocking. This could be
>>>> achieved
>>>> e.g., by letting soconnsleep/soconnwakeup use different events if the
>>>> socket is being closed and propagating an error code that prevents
>>>> the socket structure being from accessed from the RTEMS glue code
>>>> in this case.
>>
>>
>>
>> Hmmm .. thinking before reading. :) Sounds like a good solution. :)
>>
>
> I am yet to figure out how you detect a socket is closed in the wake
> calls. The only thing I have found is the socket state flags.
>
>>> ... or block the close until the blocked thread has returned. I have
>>> something which appears to be working for accept, and I am now
>>> looking at the other calls.
>>
>>
>>
>> This would work but could be more complicated to get right.
>>
>
> I have it working for accept. The close thread blocks until the
> accepting thread returns.
>
> I have also fixed rtems_bsdnet_close by adding 'iop->data1 = NULL;'.
> This stops close being entered.
>
>>> Using another event, say SOCLOSED is a good idea. I may look at this.
>>> Thanks for the idea.
>>
>>
>>
>> A working fix that is not TOO broad would be OK for 4.6.x.
>>
>
> The code is also in CVS HEAD so I am not sure I understand.
>
--
Joel Sherrill, Ph.D. Director of Research & Development
joel at OARcorp.com On-Line Applications Research
Ask me about RTEMS: a free RTOS Huntsville AL 35805
Support Available (256) 722-9985
More information about the users
mailing list