X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Fvfs%2Fselect.c;h=18fdab766503e3d05ebfb6be444c207a2f590339;hb=930fe819133ddb444bc6c22df09baf788183f6ad;hp=c695bb6c2aa0e7cb2352a09daf6203c8b7a8f699;hpb=e42035c38b65d428672b128f9ae253f81b2ced96;p=tpg%2Facess2.git diff --git a/Kernel/vfs/select.c b/Kernel/vfs/select.c index c695bb6c..18fdab76 100644 --- a/Kernel/vfs/select.c +++ b/Kernel/vfs/select.c @@ -44,9 +44,9 @@ struct sVFS_SelectThread // int VFS_MarkFull(tVFS_Node *Node, BOOL IsBufferFull); // int VFS_MarkAvaliable(tVFS_Node *Node, BOOL IsDataAvaliable); // int VFS_MarkError(tVFS_Node *Node, BOOL IsErrorState); - int VFS_int_Select_GetType(enum eVFS_SelectTypes Type, tVFS_Node *Node, tVFS_SelectList ***List, int **Flag, int *WantedFlag, int *MaxAllowed); - int VFS_int_Select_Register(tVFS_SelectThread *Thread, int MaxHandle, fd_set *Handles, enum eVFS_SelectTypes Type, BOOL IsKernel); - int VFS_int_Select_Deregister(tVFS_SelectThread *Thread, int MaxHandle, fd_set *Handles, enum eVFS_SelectTypes Type, BOOL IsKernel); + int VFS_int_Select_GetType(int Type, tVFS_Node *Node, tVFS_SelectList ***List, int **Flag, int *WantedFlag, int *MaxAllowed); + int VFS_int_Select_Register(tVFS_SelectThread *Thread, int MaxHandle, fd_set *Handles, int Type, BOOL IsKernel); + int VFS_int_Select_Deregister(tVFS_SelectThread *Thread, int MaxHandle, fd_set *Handles, int Type, BOOL IsKernel); int VFS_int_Select_AddThread(tVFS_SelectList *List, tVFS_SelectThread *Thread, int MaxAllowed); void VFS_int_Select_RemThread(tVFS_SelectList *List, tVFS_SelectThread *Thread); void VFS_int_Select_SignalAll(tVFS_SelectList *List); @@ -54,40 +54,47 @@ void VFS_int_Select_SignalAll(tVFS_SelectList *List); // === GLOBALS === // === FUNCTIONS === -int VFS_SelectNode(tVFS_Node *Node, enum eVFS_SelectTypes Type, tTime *Timeout) +int VFS_SelectNode(tVFS_Node *Node, int TypeFlags, tTime *Timeout, const char *Name) { tVFS_SelectThread *thread_info; - tVFS_SelectList **list; - int *flag, wanted, maxAllowed; - - ENTER("pNode iType pTimeout", Node, Type, Timeout); + int ret, type; - if( VFS_int_Select_GetType(Type, Node, &list, &flag, &wanted, &maxAllowed) ) { - LEAVE('i', -1); - return -1; - } + ENTER("pNode iTypeFlags pTimeout", Node, TypeFlags, Timeout); thread_info = malloc(sizeof(tVFS_SelectThread)); - if(!thread_info) return -1; - - Semaphore_Init(&thread_info->SleepHandle, 0, 0, "VFS_SelectNode()", ""); + if(!thread_info) LEAVE_RET('i', -1); + + Semaphore_Init(&thread_info->SleepHandle, 0, 0, "VFS_SelectNode()", Name); - LOG("list=%p, flag=%p, wanted=%i, maxAllowed=%i", list, flag, wanted, maxAllowed); + // Initialise + for( type = 0; type < 3; type ++ ) + { + tVFS_SelectList **list; + int *flag, wanted, maxAllowed; + if( !(TypeFlags & (1 << type)) ) continue; + if( VFS_int_Select_GetType(type, Node, &list, &flag, &wanted, &maxAllowed) ) { + free(thread_info); + LEAVE('i', -1); + return -1; + } - // Alloc if needed - if( !*list ) { - *list = calloc(1, sizeof(tVFS_SelectList)); - } + // Alloc if needed + if( !*list ) *list = calloc(1, sizeof(tVFS_SelectList)); - VFS_int_Select_AddThread(*list, thread_info, maxAllowed); - if( *flag == wanted ) - { - VFS_int_Select_RemThread(*list, thread_info); - free(thread_info); - LEAVE('i', 1); - return 1; + VFS_int_Select_AddThread(*list, thread_info, maxAllowed); + if( *flag == wanted ) + { + VFS_int_Select_RemThread(*list, thread_info); + free(thread_info); + LEAVE('i', 1); + return 1; + } } - + + // - Fast return for polling + if( Timeout && *Timeout == 0 ) return 0; + + // Wait for things if( !Timeout || *Timeout > 0 ) { LOG("Semaphore_Wait()"); @@ -95,13 +102,23 @@ int VFS_SelectNode(tVFS_Node *Node, enum eVFS_SelectTypes Type, tTime *Timeout) Semaphore_Wait(&thread_info->SleepHandle, 1); } - LOG("VFS_int_Select_RemThread()"); - VFS_int_Select_RemThread(*list, thread_info); + // Get return value + ret = 0; + for( type = 0; type < 3; type ++ ) + { + tVFS_SelectList **list; + int *flag, wanted, maxAllowed; + if( !(TypeFlags & (1 << type)) ) continue; + VFS_int_Select_GetType(type, Node, &list, &flag, &wanted, &maxAllowed); + LOG("VFS_int_Select_RemThread()"); + VFS_int_Select_RemThread(*list, thread_info); + ret = ret || *flag == wanted; + } free(thread_info); - LEAVE('i', *flag == wanted); - return *flag == wanted; + LEAVE('i', ret); + return ret; } int VFS_Select(int MaxHandle, fd_set *ReadHandles, fd_set *WriteHandles, fd_set *ErrHandles, tTime *Timeout, BOOL IsKernel) @@ -112,9 +129,12 @@ int VFS_Select(int MaxHandle, fd_set *ReadHandles, fd_set *WriteHandles, fd_set thread_info = malloc(sizeof(tVFS_SelectThread)); if(!thread_info) return -1; - Semaphore_Init(&thread_info->SleepHandle, 0, -1, "VFS_Select()", ""); + ENTER("iMaxHandle pReadHandles pWriteHandles pErrHandles pTimeout bIsKernel", + MaxHandle, ReadHandles, WriteHandles, ErrHandles, Timeout, IsKernel); - // Notes: The idea is to make sure we onlt enter wait (on the semaphore) + Semaphore_Init(&thread_info->SleepHandle, 0, 0, "VFS_Select()", ""); + + // Notes: The idea is to make sure we only enter wait (on the semaphore) // if we are going to be woken up (either by an event at a later time, // or by an event that happened while or before we were registering). // Hence, register must happen _before_ we check the state flag @@ -126,6 +146,8 @@ int VFS_Select(int MaxHandle, fd_set *ReadHandles, fd_set *WriteHandles, fd_set ret += VFS_int_Select_Register(thread_info, MaxHandle, WriteHandles, 1, IsKernel); ret += VFS_int_Select_Register(thread_info, MaxHandle, ErrHandles, 2, IsKernel); + LOG("Register ret = %i", ret); + // If there were events waiting, de-register and return if( ret ) { @@ -133,6 +155,7 @@ int VFS_Select(int MaxHandle, fd_set *ReadHandles, fd_set *WriteHandles, fd_set ret += VFS_int_Select_Deregister(thread_info, MaxHandle, WriteHandles, 1, IsKernel); ret += VFS_int_Select_Deregister(thread_info, MaxHandle, ErrHandles, 2, IsKernel); free(thread_info); + LEAVE('i', ret); return ret; } @@ -142,6 +165,7 @@ int VFS_Select(int MaxHandle, fd_set *ReadHandles, fd_set *WriteHandles, fd_set if( !Timeout || *Timeout > 0 ) { ret = Semaphore_Wait(&thread_info->SleepHandle, 1); + // TODO: Do something with ret? } // Fill output (modify *Handles) @@ -150,6 +174,7 @@ int VFS_Select(int MaxHandle, fd_set *ReadHandles, fd_set *WriteHandles, fd_set ret += VFS_int_Select_Deregister(thread_info, MaxHandle, WriteHandles, 1, IsKernel); ret += VFS_int_Select_Deregister(thread_info, MaxHandle, ErrHandles, 2, IsKernel); free(thread_info); + LEAVE('i', ret); return ret; } @@ -187,7 +212,7 @@ int VFS_MarkError(tVFS_Node *Node, BOOL IsErrorState) } // --- Internal --- -int VFS_int_Select_GetType(enum eVFS_SelectTypes Type, tVFS_Node *Node, tVFS_SelectList ***List, int **Flag, int *WantedFlag, int *MaxAllowed) +int VFS_int_Select_GetType(int Type, tVFS_Node *Node, tVFS_SelectList ***List, int **Flag, int *WantedFlag, int *MaxAllowed) { // Get the type of the listen switch(Type) @@ -220,7 +245,7 @@ int VFS_int_Select_GetType(enum eVFS_SelectTypes Type, tVFS_Node *Node, tVFS_Sel /** * \return Number of files with an action */ -int VFS_int_Select_Register(tVFS_SelectThread *Thread, int MaxHandle, fd_set *Handles, enum eVFS_SelectTypes Type, BOOL IsKernel) +int VFS_int_Select_Register(tVFS_SelectThread *Thread, int MaxHandle, fd_set *Handles, int Type, BOOL IsKernel) { int i, numFlagged = 0; tVFS_SelectList **list; @@ -229,7 +254,7 @@ int VFS_int_Select_Register(tVFS_SelectThread *Thread, int MaxHandle, fd_set *Ha if( !Handles ) return 0; - ENTER("pThread iMaxHandle pHandles iType BIsKernel", Thread, MaxHandle, Handles, Type, IsKernel); + ENTER("pThread iMaxHandle pHandles iType iIsKernel", Thread, MaxHandle, Handles, Type, IsKernel); for( i = 0; i < MaxHandle; i ++ ) { @@ -237,6 +262,7 @@ int VFS_int_Select_Register(tVFS_SelectThread *Thread, int MaxHandle, fd_set *Ha // Is the descriptor set if( !FD_ISSET(i, Handles) ) continue; + LOG("FD #%i", i); handle = VFS_GetHandle( i | (IsKernel?VFS_KERNEL_FLAG:0) ); // Is the handle valid? @@ -281,7 +307,7 @@ int VFS_int_Select_Register(tVFS_SelectThread *Thread, int MaxHandle, fd_set *Ha /** * \return Number of files with an action */ -int VFS_int_Select_Deregister(tVFS_SelectThread *Thread, int MaxHandle, fd_set *Handles, enum eVFS_SelectTypes Type, BOOL IsKernel) +int VFS_int_Select_Deregister(tVFS_SelectThread *Thread, int MaxHandle, fd_set *Handles, int Type, BOOL IsKernel) { int i, numFlagged = 0; tVFS_SelectList **list; @@ -289,7 +315,7 @@ int VFS_int_Select_Deregister(tVFS_SelectThread *Thread, int MaxHandle, fd_set * if( !Handles ) return 0; - ENTER("pThread iMaxHandle pHandles iType BIsKernel", Thread, MaxHandle, Handles, Type, IsKernel); + ENTER("pThread iMaxHandle pHandles iType iIsKernel", Thread, MaxHandle, Handles, Type, IsKernel); for( i = 0; i < MaxHandle; i ++ ) { @@ -297,6 +323,7 @@ int VFS_int_Select_Deregister(tVFS_SelectThread *Thread, int MaxHandle, fd_set * // Is the descriptor set if( !FD_ISSET(i, Handles) ) continue; + LOG("FD #%i", i); handle = VFS_GetHandle( i | (IsKernel?VFS_KERNEL_FLAG:0) ); // Is the handle valid? @@ -462,6 +489,8 @@ void VFS_int_Select_SignalAll(tVFS_SelectList *List) int i; tVFS_SelectListEnt *block; + if( !List ) return ; + ENTER("pList", List); // Lock to avoid concurrency issues @@ -474,9 +503,9 @@ void VFS_int_Select_SignalAll(tVFS_SelectList *List) { for( i = 0; i < NUM_THREADS_PER_ALLOC; i ++ ) { - LOG("block->Threads[i] = %p", block->Threads[i]); if( block->Threads[i] ) { + LOG("block(%p)->Threads[%i] = %p", block, i, block->Threads[i]); Semaphore_Signal( &block->Threads[i]->SleepHandle, 1 ); } }