[erlang-questions] Best way to kill an async thread in a linked in driver?

Mazen Harake <>
Fri Aug 13 00:21:14 CEST 2010

  Sorry, I should have been a bit more clear:
I need to do things in Erlang space while I'm waiting for input, such as 
telling the driver to print out a character at pos y,x.

This is the reason I can't be blocked in the driver.

Still... I may have missed something, you are more than welcome to 
enlighten me :):)


On 13/08/2010 01:14, Mazen Harake wrote:
>  Hmm... I'm not sure what you mean but the part I do understand is 
> that select() blocks... right? I can't have anything that blocks in 
> the driver since I must be able to interact with it as I'm waiting for 
> input. E.g. I need to update a certain part of the screen even if the 
> user is not pressing any buttons.
> I don't see how select() would make any difference? Perhaps I 
> misunderstood you, could you explain a bit more on how that would 
> work? Or perhaps point me to some direction?
> Thanks for feedback,
> /M
> On 12/08/2010 14:42, Kresten Krab Thorup wrote:
>> I'd write the driver using select and non-blocking reads; that way 
>> you would not need async threads at all.
>> Kresten
>> On Aug 12, 2010, at 10:31 , Mazen Harake wrote:
>>>   It was late yesterday and despite 2 coffees and a nice breakfast I
>>> still can't solve this one. Maybe a nudge in the right direction 
>>> anyone?
>>> Scenario:
>>> I have a linked in driver; cecho [1], when ever I want to read input I
>>> disable input to Erlang (-noinput) and use the getch() function in C
>>> instead (never mind why ;)). This function is run in a seperate async
>>> thread using driver_async() [2][3], and blocks at getch(). When a
>>> character is read it sends a message back to Erlang (driver_output())
>>> and then the thread exits, when the message comes back to Erlang the
>>> character is sent to the requester and the thread is restarted (which
>>> again blocks at getch()).
>>> Later if I do an erlang:halt(0) ("graceful halt") the thread is still
>>> lingering despite having closed the port[4] (which, Afaik should close
>>> the thread as well) but it seems stay alive somehow. erlang:halt(1) 
>>> kill
>>> it immediately so it is not a problem.
>>> Questions:
>>> 1) Is my "analysis" correct? Is this infact what is happening? Anyone
>>> who can explain this behaviour (I.e. why it lingers on)?
>>> 2) If Question 1 then; what is the best way to kill the thread when I
>>> exit? driver_async_cancel() only works for threads that are not
>>> executing (according to Documentation) so what to do? I did an ugly
>>> workaround which sets a global flag and then I timeout the getch()
>>> operation and read for ERR. If I get an ERR I just read the abort flag
>>> and if it is set I just die otherwise I try to getch() again. This
>>> avoids hanging around for more then a tenth of a second but it is 
>>> pretty
>>> ugly in my oppinion and I'm forced to go into halfdelay mode which 
>>> means
>>> I can not allow this option outside of the driver because I become
>>> dependent on it. I'd rather do it the "right way" if there is such a 
>>> way.
>>> References: (Links given as commit Ids so that if someone searches then
>>> they get relevant code and not the latest)
>>> [1]
>>> http://github.com/mazenharake/cecho/tree/199fd342ba186e1154c32dbfdcf2d9222e25f9f4 
>>> [2]
>>> http://github.com/mazenharake/cecho/blob/199fd342ba186e1154c32dbfdcf2d9222e25f9f4/c_src/cecho.c#L119 
>>>      static void request(ErlDrvData drvstate, char *buf, int buflen) {
>>> state *st = (state *)drvstate;
>>> driver_async(st->drv_port, NULL, loop_getch, (void *)st, NULL);
>>>      }
>>> [3]
>>> http://github.com/mazenharake/cecho/blob/199fd342ba186e1154c32dbfdcf2d9222e25f9f4/c_src/cecho.c#L557 
>>> void loop_getch(void *arg) {
>>>      state *st = (state *)arg;
>>>      ei_x_buff eixb;
>>>      int keycode;
>>>      ei_x_new_with_version(&eixb);
>>>      keycode = getch();
>>>      integer(&eixb, keycode);
>>>      driver_output(st->drv_port, eixb.buff, eixb.index);
>>> }
>>> [4]
>>> http://github.com/mazenharake/cecho/blob/199fd342ba186e1154c32dbfdcf2d9222e25f9f4/src/cecho_srv.erl#L76 
>>> terminate(_Reason, State) ->
>>>      do_call(State#state.port, ?ENDWIN),
>>>      do_call(State#state.port, ?CURS_SET, ?ceCURS_NORMAL),
>>>      erlang:port_close(State#state.port),
>>>      erl_ddll:unload("cecho").
>>> ________________________________________________________________
>>> erlang-questions (at) erlang.org mailing list.
>>> See http://www.erlang.org/faq.html
>>> To unsubscribe; mailto:
>> Kresten Krab Thorup, CTO, Trifork
> ________________________________________________________________
> erlang-questions (at) erlang.org mailing list.
> See http://www.erlang.org/faq.html
> To unsubscribe; mailto:

More information about the erlang-questions mailing list