/*! * Close a message queue * \param mqdes Queue descriptor address (user level descriptor) * \return 0 if successful, -1 otherwise and appropriate error number is set */ int sys__mq_close ( void *p ) { mqd_t *mqdes; kmq_queue_t *kq_queue; kobject_t *kobj; kmq_msg_t *kmq_msg; kthread_t *kthread; mqdes = *( (mqd_t **) p ); ASSERT_ERRNO_AND_EXIT ( mqdes, EBADF ); kobj = mqdes->ptr; ASSERT_ERRNO_AND_EXIT ( kobj, EBADF ); ASSERT_ERRNO_AND_EXIT ( list_find ( &kobjects, &kobj->list ), EBADF ); kq_queue = kobj->kobject; kq_queue = list_find_and_remove ( &kmq_queue, &kq_queue->list ); if ( !kq_queue || kq_queue->id != mqdes->id ) EXIT2 ( EBADF, EXIT_FAILURE ); kq_queue->ref_cnt--; if ( !kq_queue->ref_cnt ) { /* remove messages */ while( (kmq_msg = list_remove(&kq_queue->msg_list,FIRST,NULL)) ) kfree (kmq_msg); /* remove blocked threads */ while ( (kthread = kthreadq_remove (&kq_queue->send_q, NULL)) ) { kthread_move_to_ready ( kthread, LAST ); kthread_set_errno ( kthread, EBADF ); kthread_set_syscall_retval ( kthread, EXIT_FAILURE ); } while ( (kthread = kthreadq_remove (&kq_queue->recv_q, NULL)) ) { kthread_move_to_ready ( kthread, LAST ); kthread_set_errno ( kthread, EBADF ); kthread_set_syscall_retval ( kthread, EXIT_FAILURE ); } list_remove ( &kmq_queue, 0, &kq_queue->list ); k_free_id ( kq_queue->id ); kfree ( kq_queue->name ); kfree ( kq_queue ); } /* remove kernel object descriptor */ kfree_kobject ( kobj ); EXIT2 ( EXIT_SUCCESS, EXIT_SUCCESS ); }
/*! Internal function for removing (freeing) thread descriptor */ static void kthread_remove_descriptor ( kthread_t *kthread ) { ASSERT ( kthread ); k_free_id ( kthread->id ); kthread->id = 0; #ifdef DEBUG ASSERT( kthread == list_find_and_remove (&all_threads, &kthread->all) ); #else (void) list_remove ( &all_threads, 0, &kthread->all ); #endif kfree ( kthread ); }
/*! * Delete timer * \param ktimer Timer to delete * \return status 0 for success */ int ktimer_delete ( ktimer_t *ktimer ) { ASSERT ( ktimer ); /* remove from active timers (if it was there) */ if ( TIMER_IS_ARMED ( ktimer ) ) { list_remove ( &ktimers, 0, &ktimer->list ); ktimer_schedule (); } k_free_id ( ktimer->id ); kfree ( ktimer ); return EXIT_SUCCESS; }