|
From: Sebastian B. <sb...@us...> - 2003-02-22 16:06:14
|
Update of /cvsroot/simplemail/amiga-mui
In directory sc8-pr-cvs1:/tmp/cvs-serv6786
Modified Files:
subthreads.c
Log Message:
thread_create_message() created and use it in some places to shorten the code.
thread_handle_execute_function_message() introduced which is responible for evaluation of thread execute function message.
Use this new function in thread_wait() => now it should be possible to call functions from another thread to another thread if the latter thread is in thread_wait()
However new thread_call_xxx functions() need to be introduced first.
Index: subthreads.c
===================================================================
RCS file: /cvsroot/simplemail/amiga-mui/subthreads.c,v
retrieving revision 1.25
retrieving revision 1.26
diff -C2 -r1.25 -r1.26
*** subthreads.c 22 Feb 2003 12:14:48 -0000 1.25
--- subthreads.c 22 Feb 2003 16:06:07 -0000 1.26
***************
*** 22,26 ****
/* Define DONT_USE_THREADS to disable the multithreading */
! /* #define DONT_USE_THREADS */
#include <stdarg.h>
--- 22,26 ----
/* Define DONT_USE_THREADS to disable the multithreading */
! /*#define DONT_USE_THREADS*/
#include <stdarg.h>
***************
*** 37,41 ****
#include "subthreads_amiga.h" /* struct thread_s */
! /*#define MYDEBUG*/
#include "debug.h"
--- 37,41 ----
#include "subthreads_amiga.h" /* struct thread_s */
! /* #define MYDEBUG */
#include "debug.h"
***************
*** 55,63 ****
static struct MsgPort *thread_port;
! /* the thread, we currently allow only a single one */
! //static struct Process *thread;
static thread_t default_thread;
!
struct list thread_list;
struct thread_node
--- 55,62 ----
static struct MsgPort *thread_port;
! /* the default thread */
static thread_t default_thread;
! /* list of all subthreads */
struct list thread_list;
struct thread_node
***************
*** 67,70 ****
--- 66,71 ----
};
+ static void thread_handle_execute_function_message(struct ThreadMessage *tmsg);
+
/**************************************************************************
Remove the thread which has replied tis given tmsg
***************
*** 160,163 ****
--- 161,166 ----
while ((tmsg = (struct ThreadMessage *)GetMsg(thread_port)))
{
+ D(bug("Received Message: 0x%lx\n",tmsg));
+
if (tmsg->startup)
{
***************
*** 165,185 ****
continue;
}
! if (tmsg->function)
! {
! switch(tmsg->argcount)
! {
! case 0: tmsg->result = tmsg->function();break;
! case 1: tmsg->result = ((int (*)(void*))tmsg->function)(tmsg->arg1);break;
! case 2: tmsg->result = ((int (*)(void*,void*))tmsg->function)(tmsg->arg1,tmsg->arg2);break;
! case 3: tmsg->result = ((int (*)(void*,void*,void*))tmsg->function)(tmsg->arg1,tmsg->arg2,tmsg->arg3);break;
! case 4: tmsg->result = ((int (*)(void*,void*,void*,void*))tmsg->function)(tmsg->arg1,tmsg->arg2,tmsg->arg3,tmsg->arg4);break;
! }
! }
! if (tmsg->async)
! {
! if (tmsg->async == 2 && tmsg->argcount >= 1 && tmsg->arg1) FreeVec(tmsg->arg1);
! FreeVec(tmsg);
! }
! else ReplyMsg(&tmsg->msg);
}
}
--- 168,173 ----
continue;
}
!
! thread_handle_execute_function_message(tmsg);
}
}
***************
*** 205,208 ****
--- 193,197 ----
if (thread->thread_port = CreateMsgPort())
{
+ D(bug("Subthreaded created port at 0x%lx\n",thread->thread_port));
proc->pr_Task.tc_UserData = thread;
entry = (int(*)(void*))msg->function;
***************
*** 377,413 ****
}
- /* Call the function synchron */
- int thread_call_parent_function_sync(void *function, int argcount, ...)
- {
- #ifndef DONT_USE_THREADS
- int rc = 0;
struct ThreadMessage *tmsg = (struct ThreadMessage *)AllocVec(sizeof(struct ThreadMessage),MEMF_PUBLIC|MEMF_CLEAR);
if (tmsg)
{
! struct Process *p = (struct Process*)FindTask(NULL);
! va_list argptr;
!
! va_start(argptr,argcount);
! tmsg->msg.mn_ReplyPort = &p->pr_MsgPort;
tmsg->msg.mn_Length = sizeof(struct ThreadMessage);
tmsg->function = (int (*)(void))function;
tmsg->argcount = argcount;
! tmsg->arg1 = va_arg(argptr, void *);/*(*(&argcount + 1));*/
! tmsg->arg2 = va_arg(argptr, void *);/*(void*)(*(&argcount + 2));*/
! tmsg->arg3 = va_arg(argptr, void *);/*(void*)(*(&argcount + 3));*/
! tmsg->arg4 = va_arg(argptr, void *);/*(void*)(*(&argcount + 4));*/
tmsg->async = 0;
! va_end (arg_ptr);
PutMsg(thread_port,&tmsg->msg);
! WaitPort(&p->pr_MsgPort);
! GetMsg(&p->pr_MsgPort);
rc = tmsg->result;
FreeVec(tmsg);
}
return rc;
#else
--- 366,473 ----
}
+ /**************************************************************************
+ Returns ThreadMessage filled with the given parameters. You can manipulate
+ the returned message to be async or something else
+ **************************************************************************/
+ static struct ThreadMessage *thread_create_message(void *function, int argcount, va_list argptr)
+ {
struct ThreadMessage *tmsg = (struct ThreadMessage *)AllocVec(sizeof(struct ThreadMessage),MEMF_PUBLIC|MEMF_CLEAR);
if (tmsg)
{
! struct MsgPort *subthread_port = ((struct thread_s*)(FindTask(NULL)->tc_UserData))->thread_port;
! tmsg->msg.mn_ReplyPort = subthread_port;
tmsg->msg.mn_Length = sizeof(struct ThreadMessage);
tmsg->function = (int (*)(void))function;
tmsg->argcount = argcount;
!
! if (argcount--)
! {
! tmsg->arg1 = va_arg(argptr, void *);
! if (argcount--)
! {
! tmsg->arg2 = va_arg(argptr, void *);
! if (argcount--)
! {
! tmsg->arg3 = va_arg(argptr, void *);
! if (argcount--)
! {
! tmsg->arg4 = va_arg(argptr, void *);
! }
! }
! }
! }
tmsg->async = 0;
+ }
+ return tmsg;
+ }
+
+ /**************************************************************************
+ This will handle the execute function message
+ **************************************************************************/
+ static void thread_handle_execute_function_message(struct ThreadMessage *tmsg)
+ {
+ if (tmsg->startup) return;
+
+ if (tmsg->function)
+ {
+ switch(tmsg->argcount)
+ {
+ case 0: tmsg->result = tmsg->function();break;
+ case 1: tmsg->result = ((int (*)(void*))tmsg->function)(tmsg->arg1);break;
+ case 2: tmsg->result = ((int (*)(void*,void*))tmsg->function)(tmsg->arg1,tmsg->arg2);break;
+ case 3: tmsg->result = ((int (*)(void*,void*,void*))tmsg->function)(tmsg->arg1,tmsg->arg2,tmsg->arg3);break;
+ case 4: tmsg->result = ((int (*)(void*,void*,void*,void*))tmsg->function)(tmsg->arg1,tmsg->arg2,tmsg->arg3,tmsg->arg4);break;
+ }
+ }
+ if (tmsg->async)
+ {
+ D(bug("Freeing Message at 0x%lx\n",tmsg));
+ if (tmsg->async == 2 && tmsg->argcount >= 1 && tmsg->arg1) FreeVec(tmsg->arg1);
+ FreeVec(tmsg);
+ }
+ else
+ {
+ D(bug("Repling Message at 0x%lx\n",tmsg));
+ ReplyMsg(&tmsg->msg);
+ }
+ }
+
+ /**************************************************************************
+ Call a function in context of the parent task synchron
+ **************************************************************************/
+ int thread_call_parent_function_sync(void *function, int argcount, ...)
+ {
+ #ifndef DONT_USE_THREADS
+ va_list argptr;
+ int rc = 0;
+ struct ThreadMessage *tmsg;
! va_start(argptr,argcount);
!
! if ((tmsg = thread_create_message(function, argcount, argptr)))
! {
! struct MsgPort *subthread_port = tmsg->msg.mn_ReplyPort;
! int ready = 0;
PutMsg(thread_port,&tmsg->msg);
!
! while (!ready)
! {
! struct Message *msg;
! WaitPort(subthread_port);
!
! while ((msg = GetMsg(subthread_port)))
! {
! if (msg == &tmsg->msg) ready = 1;
! }
! }
!
rc = tmsg->result;
FreeVec(tmsg);
}
+ va_end (arg_ptr);
return rc;
#else
***************
*** 500,532 ****
{
#ifndef DONT_USE_THREADS
int rc = 0;
! struct ThreadMessage *tmsg = (struct ThreadMessage *)AllocVec(sizeof(struct ThreadMessage),MEMF_PUBLIC|MEMF_CLEAR);
! if (tmsg)
{
! struct MsgPort *subthread_port = ((struct thread_s*)(FindTask(NULL)->tc_UserData))->thread_port;
struct timer timer;
if (timer_init(&timer))
{
! va_list argptr;
!
/* we only accept positive values */
! if (millis < 1) millis = 1;
!
! va_start(argptr,argcount);
- tmsg->msg.mn_ReplyPort = subthread_port;
- tmsg->msg.mn_Length = sizeof(struct ThreadMessage);
- tmsg->function = (int (*)(void))function;
- tmsg->argcount = argcount;
- tmsg->arg1 = va_arg(argptr, void *);/*(*(&argcount + 1));*/
- tmsg->arg2 = va_arg(argptr, void *);/*(void*)(*(&argcount + 2));*/
- tmsg->arg3 = va_arg(argptr, void *);/*(void*)(*(&argcount + 3));*/
- tmsg->arg4 = va_arg(argptr, void *);/*(void*)(*(&argcount + 4));*/
- tmsg->async = 0;
-
- va_end (arg_ptr);
-
/* now send the message */
PutMsg(thread_port,&tmsg->msg);
--- 560,581 ----
{
#ifndef DONT_USE_THREADS
+ va_list argptr;
int rc = 0;
+ struct ThreadMessage *tmsg;
! va_start(argptr,argcount);
!
! if ((tmsg = thread_create_message(function, argcount, argptr)))
{
! struct MsgPort *subthread_port = tmsg->msg.mn_ReplyPort;
struct timer timer;
if (timer_init(&timer))
{
! int ready = 0;
!
/* we only accept positive values */
! if (millis < 0) millis = 0;
/* now send the message */
PutMsg(thread_port,&tmsg->msg);
***************
*** 534,538 ****
/* while the parent task should execute the message
* we regualiy call the given callback function */
! while (1)
{
ULONG timer_m = timer_mask(&timer);
--- 583,587 ----
/* while the parent task should execute the message
* we regualiy call the given callback function */
! while (!ready)
{
ULONG timer_m = timer_mask(&timer);
***************
*** 540,544 ****
ULONG mask;
! timer_send_if_not_sent(&timer,millis);
mask = Wait(timer_m|proc_m);
--- 589,594 ----
ULONG mask;
! if (millis)
! timer_send_if_not_sent(&timer,millis);
mask = Wait(timer_m|proc_m);
***************
*** 552,562 ****
if (mask & proc_m)
{
! /* the parent task has finished */
! break;
}
}
-
- /* Remove msg from port */
- GetMsg(subthread_port);
rc = tmsg->result;
timer_cleanup(&timer);
--- 602,612 ----
if (mask & proc_m)
{
! struct Message *msg;
! while ((msg = GetMsg(subthread_port)))
! {
! if (msg == &tmsg->msg) ready = 1;
! }
}
}
rc = tmsg->result;
timer_cleanup(&timer);
***************
*** 564,567 ****
--- 614,618 ----
FreeVec(tmsg);
}
+ va_end (arg_ptr);
return rc;
#else
***************
*** 592,596 ****
! /* waits until aborted and calls timer_callback periodically */
void thread_wait(void (*timer_callback(void*)), void *timer_data, int millis)
{
--- 643,650 ----
! /**************************************************************************
! Waits until aborted and calls timer_callback periodically. It's possible
! to execute functions on the threads context while in this function
! **************************************************************************/
void thread_wait(void (*timer_callback(void*)), void *timer_data, int millis)
{
***************
*** 598,609 ****
if (timer_init(&timer))
{
while (1)
{
ULONG timer_m = timer_mask(&timer);
ULONG mask;
! timer_send_if_not_sent(&timer,millis);
! mask = Wait(timer_m|SIGBREAKF_CTRL_C);
if (mask & timer_m)
{
--- 652,667 ----
if (timer_init(&timer))
{
+ struct MsgPort *subthread_port = ((struct thread_s*)(FindTask(NULL)->tc_UserData))->thread_port;
+ if (millis < 0) millis = 0;
+
while (1)
{
+ ULONG proc_m = 1UL << subthread_port->mp_SigBit;
ULONG timer_m = timer_mask(&timer);
ULONG mask;
! if (millis) timer_send_if_not_sent(&timer,millis);
! mask = Wait(timer_m|proc_m|SIGBREAKF_CTRL_C);
if (mask & timer_m)
{
***************
*** 611,614 ****
--- 669,681 ----
timer_callback(timer_data);
timer.timer_send = 0;
+ }
+
+ if (mask & proc_m)
+ {
+ struct ThreadMessage *tmsg;
+ while ((tmsg = (struct ThreadMessage*)GetMsg(subthread_port)))
+ {
+ thread_handle_execute_function_message(tmsg);
+ }
}
|