start service tasks separately in-case platforms need to perform additional set-up...
[AROS.git] / workbench / libs / camd / clusters.c
blob567d9daba17b4ed03799202b75738dceadc55875
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: English
7 */
9 #include <proto/exec.h>
10 #include <proto/utility.h>
12 #include "camd_intern.h"
14 #ifndef __amigaos4__
15 # undef DEBUG
16 # define DEBUG 1
17 # include AROS_DEBUG_H_FILE
18 #endif
21 * CLSemaphore must be obtained and the clusters mutex must
22 * not be exclusive locked.
24 void RemoveCluster(struct MidiCluster *cluster,struct CamdBase *CamdBase){
25 struct Node *node;
26 struct ClusterNotifyNode *cn;
28 if(cluster==NULL) return;
30 Remove(&cluster->mcl_Node);
32 for(node=CB(CamdBase)->clusnotifynodes.lh_Head; node->ln_Succ; node=node->ln_Succ)
33 { // notify everyone
34 cn=(struct ClusterNotifyNode *)node;
35 Signal(cn->cnn_Task, 1L << cn->cnn_SigBit);
39 if(cluster->mcl_Node.ln_Name!=NULL){
40 FreeVec(cluster->mcl_Node.ln_Name);
42 FreeMem(cluster,sizeof(struct MyMidiCluster));
47 * REQUIREMENTS
48 * CLSemaphore must be obtained and the clusters mutex must
49 * not be exclusive locked. The link must not be freed before calling.
50 * NOTE
51 * A cluster can never have both a hardware receiver and sender.
53 void LinkHasBeenRemovedFromCluster(struct MidiCluster *cluster,struct CamdBase *CamdBase){
54 struct Node *node;
55 struct DriverData *driverdata;
57 if( ! (IsListEmpty(&cluster->mcl_Receivers))){
58 node=cluster->mcl_Receivers.lh_Head;
60 while(node->ln_Succ!=NULL){
61 if(node->ln_Type==NT_USER-MLTYPE_NTypes){
63 /* We now know that the cluster has a hardware-receiver. */
65 if(IsListEmpty(&cluster->mcl_Senders)){
67 /* And we now know that the cluster has no senders. */
69 driverdata=(struct DriverData *)cluster->mcl_Receivers.lh_Head;
71 /* We mark the hardware-receiver not to be in use. */
73 if(driverdata->isOutOpen==TRUE){
74 driverdata->isOutOpen=FALSE;
76 /* And we close it if the hardware-sender is not in use either. */
78 if(driverdata->isInOpen==FALSE){
79 CloseDriver(driverdata,CamdBase);
84 break;
86 node=node->ln_Succ;
92 if( ! (IsListEmpty(&cluster->mcl_Senders))){
94 node=cluster->mcl_Senders.lh_Head;
96 while(node->ln_Succ!=NULL){
97 if(node->ln_Type==NT_USER-MLTYPE_NTypes){
99 /* We now now that the cluster only has a hardware-sender. */
101 if(IsListEmpty(&cluster->mcl_Receivers)){
103 /* And we now know that the cluster has no senders. */
105 driverdata=(struct DriverData *)cluster->mcl_Senders.lh_Head;
106 driverdata=(struct DriverData *)(((char *)driverdata-sizeof(struct Node)));
107 /* We mark the hardware-sender not to be in use. */
109 if(driverdata->isInOpen==TRUE){
110 driverdata->isInOpen=FALSE;
112 /* And we close it if the hardware-receiver is not in use either. */
114 if(driverdata->isOutOpen==FALSE){
115 CloseDriver(driverdata,CamdBase);
119 break;
121 node=node->ln_Succ;
125 return;
129 (IsListEmpty(&cluster->mcl_Receivers)) &&
130 (IsListEmpty(&cluster->mcl_Senders))
132 RemoveCluster(cluster,CamdBase);
138 CLSemaphore must be obtained first.
141 struct MidiCluster *NewCluster(char *name,struct CamdBase *CamdBase){
142 struct MyMidiCluster *mymidicluster;
143 struct MidiCluster *midicluster;
144 struct Node *node;
145 struct ClusterNotifyNode *cn;
148 mymidicluster=AllocMem(sizeof(struct MyMidiCluster),MEMF_ANY | MEMF_CLEAR | MEMF_PUBLIC);
150 if(mymidicluster==NULL) return NULL;
152 InitSemaphore(&mymidicluster->semaphore);
154 midicluster=&mymidicluster->cluster;
156 midicluster->mcl_Node.ln_Name=AllocVec(mystrlen(name) + 1,MEMF_ANY|MEMF_PUBLIC);
158 if(midicluster->mcl_Node.ln_Name==NULL){
159 FreeMem(midicluster,sizeof(struct MyMidiCluster));
160 return NULL;
163 mysprintf(CamdBase,midicluster->mcl_Node.ln_Name,"%s",name);
164 #ifndef __amigaos4__
165 NEWLIST(&midicluster->mcl_Receivers);
166 NEWLIST(&midicluster->mcl_Senders);
167 #else // ???
168 NEWLIST(midicluster->mcl_Receivers);
169 NEWLIST(midicluster->mcl_Senders);
170 #endif
171 AddTail(&CB(CamdBase)->midiclusters,&midicluster->mcl_Node);
173 for(node=CB(CamdBase)->clusnotifynodes.lh_Head; node->ln_Succ; node=node->ln_Succ)
174 { // notify everyone
175 cn=(struct ClusterNotifyNode *)node;
176 Signal(cn->cnn_Task,1L<<cn->cnn_SigBit);
180 return midicluster;
185 CLSemaphore must have been obtained before calling.
187 struct DriverData *FindReceiverDriverInCluster(struct MidiCluster *cluster){
188 struct Node *node;
190 if( ! (IsListEmpty(&cluster->mcl_Receivers))){
191 node=cluster->mcl_Receivers.lh_Head;
193 while(node->ln_Succ!=NULL){
194 if(node->ln_Type==NT_USER-MLTYPE_NTypes) return (struct DriverData *)node;
195 node=node->ln_Succ;
198 return NULL;
202 CLSemaphore must have been obtained before calling.
205 struct DriverData *FindSenderDriverInCluster(struct MidiCluster *cluster){
206 struct Node *node;
208 if( ! (IsListEmpty(&cluster->mcl_Senders))){
209 node=cluster->mcl_Senders.lh_Head;
211 while(node->ln_Succ!=NULL){
212 if(node->ln_Type==NT_USER-MLTYPE_NTypes){
213 return (struct DriverData *)(((char *)node-sizeof(struct Node)));
215 node=node->ln_Succ;
218 return NULL;
223 CLSemaphore must have been obtained before calling.
224 The clusters exclusive mutex must not have be obtained.
227 BOOL AddClusterReceiver(
228 struct MidiCluster *cluster,
229 struct Node *node,
230 ULONG *ErrorCode,
231 struct CamdBase *CamdBase
233 struct MidiLink *midilink;
234 struct DriverData *driverdata;
235 struct MyMidiCluster *mycluster=(struct MyMidiCluster *)cluster;
237 if(node->ln_Type!=NT_USER-MLTYPE_NTypes){
238 driverdata=FindSenderDriverInCluster(cluster);
239 if(driverdata!=NULL){
240 if(driverdata->isInOpen==FALSE && driverdata->isOutOpen==FALSE){
241 if(OpenDriver(driverdata,ErrorCode,CamdBase)==FALSE){
242 return FALSE;
245 driverdata->isInOpen=TRUE;
248 midilink=(struct MidiLink *)node;
249 ObtainSemaphore(&mycluster->semaphore);
250 midilink->ml_Location=cluster;
251 }else{
252 /* The receiver is a hardware-receiver, not a midilink. */
253 ObtainSemaphore(&mycluster->semaphore);
256 Enqueue(&cluster->mcl_Receivers,node);
257 ReleaseSemaphore(&mycluster->semaphore);
259 return TRUE;
264 CLSemaphore must have been obtained before calling.
267 BOOL AddClusterSender(
268 struct MidiCluster *cluster,
269 struct Node *node,
270 ULONG *ErrorCode,
271 struct CamdBase *CamdBase
273 struct MidiLink *midilink;
274 struct DriverData *driverdata;
276 if(node->ln_Type!=NT_USER-MLTYPE_NTypes){
277 driverdata=FindReceiverDriverInCluster(cluster);
278 if(driverdata!=NULL){
279 if(driverdata->isInOpen==FALSE && driverdata->isOutOpen==FALSE){
280 if(OpenDriver(driverdata,ErrorCode,CamdBase)==FALSE){
281 return FALSE;
283 driverdata->isOutOpen=TRUE;
286 midilink=(struct MidiLink *)node;
287 midilink->ml_Location=cluster;
290 Enqueue(&cluster->mcl_Senders,node);
291 return TRUE;
297 CLSemaphore must have been obtained before calling.
300 BOOL SetClusterForLink(
301 struct MidiLink *midilink,
302 char *name,
303 ULONG *ErrorCode,
304 struct CamdBase *CamdBase
306 struct MidiCluster *cluster;
307 ULONG type=midilink->ml_Node.ln_Type;
310 UnlinkMidiLink(midilink,FALSE,CamdBase);
312 midilink->ml_Location=NULL;
315 cluster=(struct MidiCluster *)FindName(&CB(CamdBase)->midiclusters,name);
317 if(cluster==NULL){
319 cluster=NewCluster(name,CamdBase);
321 if(cluster==NULL){
322 if(ErrorCode!=NULL){
323 *ErrorCode=CME_NoMem;
325 return FALSE;
329 if(type==NT_USER-MLTYPE_Receiver){
331 if(AddClusterReceiver(cluster,&midilink->ml_Node,ErrorCode,CamdBase)==FALSE){
332 return FALSE;
334 }else{
336 if(AddClusterSender(cluster,&midilink->ml_Node,ErrorCode,CamdBase)==FALSE){
337 return FALSE;
341 return TRUE;