Subject: Re: bug#25214: #25214 26.0.50; Interacting with user from threads other than the primary

From: Zhang Haijun <[email-masked]>
Date: Fri, 8 Feb 2019 02:42:22 +0000

> 在 2019年2月8日，上午1:25，Eli Zaretskii <[email-masked]> 写道：
> 
>> From: Zhang Haijun <[email-masked]>
>> CC: "[email-masked]" <[email-masked]>
>> Date: Thu, 7 Feb 2019 14:56:22 +0000
>> 
>> 
>> Sorry for my poor English and poor expression. I mean a data channel, for example a pair of fd created by pipe() or a pair of sockets created by socketpair(). producer-consumer model.
>> 
>>> If another thread writes to some fd, it means the main thread is not
>>> running, so it cannot receive the event, even if we did find the way
>>> of having an fd which can be read by one thread and written by all the
>>> others.
>> 
>> Another thread send a input request and then be blocked on a lock(for example, keybord lock, one lock per thread). The main thread(or keybord sheduler thread) then can wake up one thread and give keybord to it.
> 
> Unless the thread that listens to these requests is never blocked, I
> don't see how this could work.
> 
It listens to these requests, so it will be waked up when there is a new request arriving. It then reads the request and put it into in-box.

When user want to process an input, the following function will be called:

void Process_an_input_request(input_request)
{
	// 0. get the thread of the request
	thread_id = input_request->thread_id;
	the_thread = get_thread(thread_id);

	// 1. wake up the thread, and give keyboard to it
	Release_lock(the_thread->keyboard_using_lock);
	// 2. wait for the thread to finish
	Acquire_lock(the_thread->keyboard_finished_lock);  // will be blocked until the thread finishes the input task

	// 3. reclaim the keyboard
	Acquire_lock(the_thread->keyboard_using_lock);
	Release_lock(the_thread->keyboard_finished_lock);

	// ...
}

The above function will blocks the main thread(or keyboard sheduler thread) until the input is finished. Don’t known is it OK for emacs internal.

> And in any case, what should a non-main thread do if it wants to ask a
> question?  Asking a question involves displaying the question before
> reading the answer.  You only talked about the second part.

It can call a function like the following:

int Ask_a_question_wrapper(prompt)
{
	Send_input_request_event(Get_thread_id(), prompt);

	// 1. request the keyboard
	Acquire_lock(Current_thread()->keyboard_finished_lock);
	Acquire_lock(Current_thread()->keyboard_using_lock); // will be blocked until the main thread wake us up.

	// 2. do the real input
	result = Ask_a_question(prompt);

	// 3. give back the keyboard
	Release_lock(Current_thread()->keyboard_using_lock);
	Release_lock(Current_thread()->keyboard_finished_lock);

	return result;
}

The keyboard_using_lock shoud be acquired by the main thread initially.
Is there a simple way to let a specified thread run and wait for it to finish a task?
Maybe the client-server model is simpler, like TCP’s three way handshake.