wait.c
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:5k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* ==== wait.c ============================================================
  2.  * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *  This product includes software developed by Chris Provenzano.
  16.  * 4. The name of Chris Provenzano may not be used to endorse or promote 
  17.  *   products derived from this software without specific prior written
  18.  *   permission.
  19.  *
  20.  * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
  21.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  22.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  23.  * ARE DISCLAIMED.  IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY 
  24.  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  25.  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
  26.  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  27.  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
  28.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  29.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
  30.  * SUCH DAMAGE.
  31.  *
  32.  * Description : All the appropriate wait routines.
  33.  *
  34.  *  1.38 94/06/13 proven
  35.  *      -Started coding this file.
  36.  *
  37.  */
  38. #ifndef lint
  39. static const char rcsid[] = "$Id$";
  40. #endif
  41. #include <pthread.h>
  42. #include <signal.h>
  43. #include <sys/types.h>
  44. #include <sys/time.h>
  45. #include <pthread/posix.h>
  46. #include <sys/compat.h>
  47. #include <sys/wait.h>
  48. /* This is an UGLY hack to get wait to compile, something better is needed. */
  49. /* #define _POSIX_SOURCE
  50. #undef _POSIX_SOURCE
  51. */
  52. struct pthread_queue wait_queue = { NULL, NULL, NULL };
  53. extern void sig_handler_real();
  54. /* ==========================================================================
  55.  * wait_wakeup()
  56.  *
  57.  * This routine is called by the interrupt handler which has locked
  58.  * the current kthread semaphore. Since only threads owned by the 
  59.  * current kthread can be queue here, no additional locks are necessary.
  60.  */
  61. int wait_wakeup()
  62. {
  63. struct pthread *pthread;
  64. int ret = 0;
  65. if (pthread = pthread_queue_deq(& wait_queue)) {
  66. /* Wakeup all threads, and enqueue them on the run queue */
  67. do {
  68. pthread->state = PS_RUNNING;
  69. if (pthread->pthread_priority > ret) {
  70. ret = pthread->pthread_priority;
  71. }
  72. pthread_prio_queue_enq(pthread_current_prio_queue, pthread);
  73. } while (pthread = pthread_queue_deq(&wait_queue));
  74. return(ret);
  75. }
  76. return(NOTOK);
  77. }
  78. /* ==========================================================================
  79.  * For the wait calls, it is important that the current kthread is locked
  80.  * before the apropriate wait syscall is preformed. This way we ensure
  81.  * that there is never a case where a thread is waiting for a child but
  82.  * missed the interrupt for that child.
  83.  * Patched by William S. Lear  1997-02-02
  84.  */
  85. /* ==========================================================================
  86.  * waitpid()
  87.  */
  88. pid_t waitpid(pid_t pid, int *status, int options)
  89. {
  90.   pid_t ret;
  91.   pthread_sched_prevent();
  92.   ret = machdep_sys_waitpid(pid, status, options | WNOHANG);
  93.   /* If we are not doing nohang, try again, else return immediately */
  94.   if (!(options & WNOHANG)) {
  95.     while (ret == OK) {
  96.       /* Enqueue thread on wait queue */
  97.       pthread_queue_enq(&wait_queue, pthread_run);
  98.       /* reschedule unlocks scheduler */
  99.       SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
  100.       pthread_resched_resume(PS_WAIT_WAIT);
  101.       CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
  102.       pthread_sched_prevent();
  103.       ret = machdep_sys_waitpid(pid, status, options | WNOHANG);
  104.     }
  105.   }
  106.   pthread_sched_resume();
  107.   return(ret);
  108. }
  109. /* ==========================================================================
  110.  * wait3()
  111.  * Patched by Monty 1997-02-02
  112.  */
  113. pid_t wait3(__WAIT_STATUS status, int options, void * rusage)
  114. {
  115.   semaphore * lock;
  116.   pid_t ret;
  117.   pthread_sched_prevent();
  118.   ret = machdep_sys_wait3(status, options | WNOHANG, rusage);
  119.   /* If we are not doing nohang, try again, else return immediately */
  120.   if (!(options & WNOHANG)) {
  121.     while (ret == OK) {
  122.       /* Enqueue thread on wait queue */
  123.       pthread_queue_enq(&wait_queue, pthread_run);
  124.       /* reschedule unlocks scheduler */
  125.       SET_PF_AT_CANCEL_POINT(pthread_run); /* This is a cancel point */
  126.       pthread_resched_resume(PS_WAIT_WAIT);
  127.       CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* No longer at cancel point */
  128.       pthread_sched_prevent();
  129.       machdep_sys_wait3(status, options | WNOHANG, rusage);
  130.     }
  131.   }
  132.   pthread_sched_resume();
  133.   return(ret);
  134. }
  135. /* ==========================================================================
  136.  * wait()
  137.  */
  138. pid_t wait(__WAIT_STATUS status)
  139. {
  140. return(waitpid((pid_t)-1, (int *)status, 0));
  141. }