[erlang-questions] Port Driver. erl_drv_thread_join and ErlDrvTid reuse.
Thu Oct 11 15:11:14 CEST 2012
>> Are you calling driver_failure_atom() from your thread? That would explain this issue.
Exactly. Could you explain a little bit more why it can cause this issue (I suppose it's due to it is not thread safe)?
Phone. +7 495 2580500 ext. 1246
From: Rickard Green [mailto:]
Sent: Thursday, October 11, 2012 4:35 PM
To: Zhemzhitsky Sergey
Cc: Erlang Questions
Subject: Re: [erlang-questions] Port Driver. erl_drv_thread_join and ErlDrvTid reuse.
The tid cannot be prematurely reused in this case. The EDEADLK is due to some other reason.
Are you calling driver_failure_atom() from your thread? That would explain this issue.
On 10/11/2012 02:21 PM, Zhemzhitsky Sergey wrote:
> Hello Rickard,
> Thanks a lot for clarification.
> I'm doing erl_drv_thread_join() only once and only for threads created by erl_drv_thread_create().
> The error only happens from time to time in the following scenario:
> 1. Erlang process, I send messages from the ddriver to, dies for some
> reason 2. Driver callback process_exit fires.
> 3. From the driver thread I'm trying to send the final message to the
> dead erlang process with driver_send_term 4. As the erlang process is
> dead, driver_send_term fails 5. As driver_send_term fails I'm doing driver_failure_atom to kill linked process.
> Here two things happen:
> 6.1 (*stop)(ErlDrvData drv_data) executes as linked process has been
> killed by driver_failure_atom
> 6.2 Thread, started in the driver, exists
> When (*stop)(ErlDrvData drv_data) executes erl_drv_thread_join is called for all the threads started in the driver.
> So something wrong happens that leads to tid reuse.
> Best Regards,
> -----Original Message-----
> From: Rickard Green [mailto:]
> Sent: Wednesday, October 10, 2012 11:13 PM
> To: Zhemzhitsky Sergey
> Cc: Erlang Questions
> Subject: Re: [erlang-questions] Port Driver. erl_drv_thread_join and ErlDrvTid reuse.
>> >From time to time erl_drv_thread_join returns error EDEADLK=35, i.e. the current thread (scheduler thread) tries to join itself.
>> According to the documentation “A Thread identifier may be reused very quickly after a thread has terminated. Therefore, if a thread corresponding to one of the involved thread identifiers has terminated since the thread identifier was saved, the result of erl_drv_equal_tids() might not give the expected result.”
>> I suppose that thread terminates earlier then erl_drv_thread_join call happens, so ErlDrvTid is already reused.
> This reuse will not cause problems for erl_drv_thread_join() as long as it is used correctly (a tid wont be reused until after the thread has been joined). erl_drv_thread_join() will also refuse to join threads not created by erl_drv_thread_create(), and would in case the scheduler thread tried to join itself fail with EINVAL.
>> So the question is how to use erl_drv_thread_join properly and how to guarantee that the saved ErlDrvTid value points to the same data that was returned from erl_drv_thread_create?
> It is important that the thread is joined once and *only* once. Are you sure that you don't do two calls to erl_drv_thread_join() for the same thread?
> Rickard Green, Erlang/OTP, Ericsson AB.
> CONFIDENTIALITY NOTICE: This email and any files attached to it may be conf idential. If you are not the intended recipient you are notified that using, copying, distributing or taking any action in reliance on the contents of this information is strictly prohibited. If you have received this email in error please notify the sender and delete this email.
Rickard Green, Erlang/OTP, Ericsson AB.
More information about the erlang-questions