Exetools  

Go Back   Exetools > General > Developer Section

Notices

 
 
Thread Tools Display Modes
Prev Previous Post   Next Post Next
  #3  
Old 07-29-2019, 01:02
chants chants is offline
VIP
 
Join Date: Jul 2016
Posts: 826
Rept. Given: 47
Rept. Rcvd 50 Times in 31 Posts
Thanks Given: 737
Thanks Rcvd at 1,140 Times in 529 Posts
chants Reputation: 51
Here is the final clean code of the above which is polling-free since polling technically should not be done in a waiting loop ever in modern OS code where the OS can always schedule that much more safely and efficiently:

Code:
	/// Execute code in the main thread - to be used with execute_sync().
	struct execFunctor : public exec_request_t
	{
		std::function<void()> fun;
		qsemaphore_t finishSem;
		int* taskNo;
		execFunctor(std::function<void()> f, qsemaphore_t qs, int* tsk) : fun(f), finishSem(qs), taskNo(tsk) {}
		virtual ~execFunctor(void) override {}
		/// Callback to be executed.
		/// If this function raises an exception, execute_sync() never returns.
		virtual int idaapi execute(void)
		{
			fun();
			*taskNo = -1;
			qsem_post(finishSem);
			return 0;
		}
	};
	void IdaCallback::executeOnMainThread(std::function<void()> fun)
	{
		execFunctor* ef = new execFunctor(fun, di->termSem, &di->uiExecutingTask);
		{ //must be a locked unit otherwise race condition can occur
			qmutex_locker_t lock(di->qm);
			if (di->exiting) return;
			di->uiExecutingTask = execute_sync(*ef, MFF_NOWAIT);
		}
		qsem_wait(di->termSem, -1);
		if (di->uiExecutingTask == -1) delete ef;
	}
Forced termination (of course the qsem_create/qsem_free must be called at program initialization and termination):
Code:
		{ //must be a locked unit otherwise race condition can occur
			qmutex_locker_t lock(decompInfo->qm);
			decompInfo->exiting = true;			
			if (decompInfo->uiExecutingTask != -1) {
				if (cancel_exec_request(decompInfo->uiExecutingTask)) {
					qsem_post(decompInfo->termSem);
				}
			}
		}
Note that qwait_for_handles despite the docs not making it clear works for semaphores so you can do a multiple wait (WaitForMultipleObjects/select) e.g.:
Code:
int idx = -1;
qhandle_t handles[2] = { finishSem, termSem };
while (qwait_for_handles(&idx, handles, 2, 0, -1), idx == -1) {}
Reply With Quote
The Following User Says Thank You to chants For This Useful Post:
nimaarek (08-11-2019)
 


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Need some tips on in memory patching of a .Net dll Sailor_EDA General Discussion 4 05-30-2011 22:27
new tricks of armadillo LaBBa General Discussion 4 01-30-2004 18:17
tips? NE1 General Discussion 3 08-27-2002 03:45


All times are GMT +8. The time now is 16:10.


Always Your Best Friend: Aaron, JMI, ahmadmansoor, ZeNiX, chessgod101
( Since 1998 )