3 * - By John Hodge (thePowersGang)
11 #include <threads_int.h>
17 * \fn int Proc_SendMessage(Uint Dest, int Length, void *Data)
18 * \brief Send an IPC message
19 * \param Dest Destination Thread
20 * \param Length Length of the message
21 * \param Data Message data
23 int Proc_SendMessage(Uint Dest, int Length, void *Data)
28 ENTER("iDest iLength pData", Dest, Length, Data);
30 if(Length <= 0 || !Data) {
35 // TODO: Check message length against global/per-thread maximums
36 // TODO: Restrict queue length
39 thread = Threads_GetThread( Dest );
40 if(!thread) LEAVE_RET('i', -1);
41 LOG("Destination %p(%i %s)", thread, thread->TID, thread->ThreadName);
44 SHORTLOCK( &thread->IsLocked );
46 // Check if thread is still alive
47 if(thread->Status == THREAD_STAT_DEAD) {
48 SHORTREL( &thread->IsLocked );
53 msg = malloc( sizeof(tMsg)+Length );
55 msg->Source = Proc_GetCurThread()->TID;
57 memcpy(msg->Data, Data, Length);
59 // If there are already messages
60 if(thread->LastMessage) {
61 thread->LastMessage->Next = msg;
62 thread->LastMessage = msg;
64 thread->Messages = msg;
65 thread->LastMessage = msg;
68 SHORTREL(&thread->IsLocked);
71 LOG("Waking %p (%i %s)", thread, thread->TID, thread->ThreadName);
72 Threads_PostEvent( thread, THREAD_EVENT_IPCMSG );
78 * \fn int Proc_GetMessage(Uint *Source, void *Buffer)
79 * \brief Gets a message
80 * \param Source Where to put the source TID
81 * \param BufSize Size of \a Buffer, only this many bytes will be copied
82 * \param Buffer Buffer to place the message data (set to NULL to just get message length)
83 * \return Message length
85 int Proc_GetMessage(Uint *Source, Uint BufSize, void *Buffer)
89 tThread *cur = Proc_GetCurThread();
91 ENTER("pSource xBufSize pBuffer", Source, BufSize, Buffer);
93 // Check if queue has any items
100 SHORTLOCK( &cur->IsLocked );
103 *Source = cur->Messages->Source;
104 LOG("*Source = %i", *Source);
107 // Get message length
109 ret = cur->Messages->Length;
110 SHORTREL( &cur->IsLocked );
116 if(Buffer != GETMSG_IGNORE)
118 if( !CheckMem( Buffer, BufSize ) )
120 LOG("Invalid buffer");
122 SHORTREL( &cur->IsLocked );
126 if( BufSize < cur->Messages->Length )
127 Log_Notice("Threads", "Buffer of 0x%x passed, but 0x%x long message, truncated",
128 BufSize, cur->Messages->Length);
129 else if( BufSize < cur->Messages->Length )
130 BufSize = cur->Messages->Length;
133 LOG("Copied to buffer");
134 memcpy(Buffer, cur->Messages->Data, BufSize);
136 ret = cur->Messages->Length;
140 cur->Messages = cur->Messages->Next;
141 // - Removed last message? Clear the end-of-list pointer
142 if(cur->Messages == NULL) cur->LastMessage = NULL;
143 // > Otherwise, re-mark the IPCMSG event flag
144 else cur->EventState |= THREAD_EVENT_IPCMSG;
146 SHORTREL( &cur->IsLocked );
148 free(tmp); // Free outside of lock