2 * Amiga Generic Set - set of libraries and includes to ease sw development for all Amiga platforms
3 * Copyright (C) 2001-2011 Tomasz Wiszkowski Tomasz.Wiszkowski at gmail.com.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include <exec/ports.h>
23 #include <exec/semaphores.h>
24 #include <dos/dosextens.h>
25 #include <dos/dostags.h>
26 #include <libclass/utility.h>
27 #include <libclass/exec.h>
28 #include <libclass/dos.h>
29 #include <dos/dosextens.h>
30 #include "HookAttrT.h"
33 #include "LibrarySpool.h"
36 #define NP_CodeType TAG_IGNORE
37 #define CODETYPE_PPC 0
40 using namespace GenNS
;
48 NP_Entry
, (ULONG
)&__proc_init_code
,
50 NP_Name
, (unsigned long)hName
.Data(),
51 NP_CodeType
, CODETYPE_PPC
,
55 pProcess
= DOS
->CreateNewProc((TagItem
*)tags
);
56 p
= Exec
->CreateMsgPort();
58 m
->mn_Length
= sizeof(Message
);
59 m
->mn_Node
.ln_Name
= (char*)this;
61 Exec
->PutMsg(&pProcess
->pr_MsgPort
, m
);
64 Exec
->DeleteMsgPort (p
);
68 void Thread::Terminate()
70 if (!Exec
->AttemptSemaphore(pSemaphore
))
72 Exec
->Signal(&pProcess
->pr_Task
, lKillSignal
);
73 Exec
->ObtainSemaphore(pSemaphore
);
75 Exec
->ReleaseSemaphore(pSemaphore
);
78 bool Thread::IsTerminated()
80 if (Exec
->AttemptSemaphore(pSemaphore
))
82 Exec
->ReleaseSemaphore(pSemaphore
);
88 void Thread::WaitTerminated()
90 Exec
->ObtainSemaphore(pSemaphore
);
91 Exec
->ReleaseSemaphore(pSemaphore
);
94 unsigned long Thread::GetSignals()
96 return lKillSignal
| pTimer
->GetSignals() | pPort
->GetSignals();
99 bool Thread::HandleSignals(int32 ATimeout
)
101 return HandleSignals(ATimeout
, 0);
104 bool Thread::HandleSignals(int32 ATimeout
, uint32 ASignals
)
106 unsigned long lSignals
= ASignals
;
111 if ((ATimeout
!= 0) && (ATimeout
!= -1))
113 pTimer
->AddRequest(ATimeout
);
115 else if (ATimeout
== 0)
117 pTimer
->AbortRequest();
120 lSignals
|= GetSignals();
123 pPort
->HandleSignals(); // if there are any pending messages, handle them at once
124 if (ATimeout
) // if timeout has been set...
125 lRes
= Exec
->Wait(lSignals
); // wait for any signal or timeout
127 lRes
= Exec
->SetSignal(0, lSignals
); // just check signals
129 if (lRes
& lKillSignal
) // if we got killed
130 return true; // exit immediately
131 if (lRes
&pTimer
->GetSignals())
133 if (lRes
&pPort
->GetSignals()) // if we received a new message
134 pPort
->HandleSignals(); // take care of all messages
135 if (lRes
&~pPort
->GetSignals()) // otherwise, if it was a timer or any other signal
136 return false; // quit & report
137 } while (ATimeout
); // eventually loop.
141 bool Thread::IsTimerSignal()
146 void Thread::__proc_init_code()
148 Process
*p
; // pointer to this process
149 Message
*m
; // pointer to received message
150 Thread
*d
; // pointer to the class
152 p
= (Process
*) Exec
->FindTask(0); // get process message
153 Exec
->WaitPort(&p
->pr_MsgPort
); // we expect our class pointer
154 m
= Exec
->GetMsg(&p
->pr_MsgPort
); // handle it
155 d
= (Thread
*)m
->mn_Node
.ln_Name
; // get class pointer
156 d
->lKillSignal
= 1<<Exec
->AllocSignal(-1); // we dont have to free it.
157 d
->pPort
= new Port(0);
158 d
->pTimer
= new Timer();
159 Exec
->ObtainSemaphore(d
->pSemaphore
);
161 d
->hHook(d
, d
->pData
);
165 Exec
->ReleaseSemaphore(d
->pSemaphore
);
168 Thread::Thread(const char* AName
, const Hook
*AHook
, void* AData
) :
173 pSemaphore
= new SignalSemaphore
;
174 Exec
->InitSemaphore(pSemaphore
);
178 Thread::Thread(const char* AName
) :
183 hDefault
.Initialize(this, &Thread::fDefaultHandler
);
184 pSemaphore
= new SignalSemaphore
;
185 Exec
->InitSemaphore(pSemaphore
);
195 void Thread::SetHandler(const Hook
*AHandler
)
197 pPort
->Handler
= AHandler
;
200 void Thread::DoAsync(unsigned long ACommand
, void* ApData
)
202 pPort
->DoAsync(ACommand
, ApData
);
205 unsigned long Thread::DoSync(unsigned long ACommand
, void* ApData
)
207 return pPort
->DoSync(ACommand
, ApData
);
210 void Thread::ProcMessages()
212 pPort
->HandleSignals();
215 unsigned long Thread::fDefaultHandler(struct Thread
*pThis
, void*)
217 pThis
->HandleSignals(0xffffffff);