int main( int ac, char *av[] ) { pthread_t th[5]; int i; M_t *pM; int Ret; void *pRet; QueueInit( &Queue ); /* 1. timeout */ printf("### 1. 0s timed_wait timeout ###\n"); pthread_create( &th[0], NULL, ThreadWait, (void*)0 ); pRet = NULL; pthread_join( th[0], &pRet ); ASSERT( (int)(intptr_t)(pRet) == ETIMEDOUT ); /* 2. timeout */ printf("### 2. 10s timed_wait timeout ###\n"); pthread_create( &th[0], NULL, ThreadWait, (void*)(10*1000) ); pRet = NULL; pthread_join( th[0], &pRet ); ASSERT( (int)(intptr_t)(pRet) == ETIMEDOUT ); /* 3. timeout */ printf("### 3. 10s timed_wait receive and timeout###\n"); pthread_create( &th[0], NULL, ThreadWait, (void*)(10*1000) ); pM = M_Create( 3 ); Ret = QueuePostEntry( &Queue, pM, m_Lnk ); if( Ret < 0 ) goto err; pRet = NULL; pthread_join( th[0], &pRet ); ASSERT( (int)(intptr_t)(pRet) == ETIMEDOUT ); /* 4. one for-ever-wait thread */ printf("### 4. one for_ever_wait thread ###\n"); pthread_create( &th[0], NULL, ThreadWait, (void*)FOREVER ); pM = M_Create( 4 ); Ret = QueuePostEntry( &Queue, pM, m_Lnk ); if( Ret < 0 ) goto err; sleep( 1 ); /* 5. multi for-ever-wait threads */ printf("### 5. multi for_ever_wait threads ###\n"); pthread_create( &th[1], NULL, ThreadWait, (void*)FOREVER ); pthread_create( &th[2], NULL, ThreadWait, (void*)FOREVER ); pthread_create( &th[3], NULL, ThreadWait, (void*)FOREVER ); pthread_create( &th[4], NULL, ThreadWait, (void*)FOREVER ); pM = M_Create( 5 ); Ret = QueuePostEntry( &Queue, pM, m_Lnk ); if( Ret < 0 ) goto err; sleep( 1 ); /* 6. suspend/resume */ printf("### 6. suspend / count / resume###\n"); QueueSuspend( &Queue ); QueueMax(&Queue, 1 ); pM = M_Create( 6 ); Ret = QueuePostEntry( &Queue, pM, m_Lnk ); printf("Posted to suspended Queue Ret=%d Cnt=%d Omitted=%d\n", Ret, QueueCnt(&Queue), QueueOmitted(&Queue)); pM = M_Create( 61 ); Ret = QueuePostEntry( &Queue, pM, m_Lnk ); printf("Posted to suspended Queue Ret=%d Cnt=%d Omitted=%d\n", Ret, QueueCnt(&Queue), QueueOmitted(&Queue)); pM = M_Create( 62 ); Ret = QueuePostEntry( &Queue, pM, m_Lnk ); printf("Posted to suspended Queue Ret=%d Cnt=%d Omitted=%d\n", Ret, QueueCnt(&Queue), QueueOmitted(&Queue)); sleep( 1 ); printf("q_cnt=%d\n", QueueCnt( &Queue ) ); printf("Resume Queue\n"); QueueResume( &Queue ); sleep( 1 ); /* 7. Abort */ printf("### 7. Abort ###\n"); QueueAbort( &Queue, 9 ); sleep( 10 ); for( i = 0; i < 5; i++ ) { pRet = NULL; pthread_join( th[i], &pRet ); ASSERT( (int)(intptr_t)(pRet) == SIGKILL ); } QueueDestroy( &Queue ); printf("=== OK ===\n"); return( 0 ); err: printf("=== NG ===\n"); return( -1 ); }
// --------------------------------------------------------------------------- // setup_que: Set up a queue entry. // static BQUE *setup_que ( dbref executor, dbref caller, dbref enactor, int eval, char *command, int nargs, char *args[], reg_ref *sargs[] ) { // Can we run commands at all? // if (Halted(executor)) { return NULL; } // Make sure executor can afford to do it. // int a = mudconf.waitcost; if (mudconf.machinecost && RandomINT32(0, mudconf.machinecost-1) == 0) { a++; } if (!payfor(executor, a)) { notify(Owner(executor), "Not enough money to queue command."); return NULL; } // Wizards and their objs may queue up to db_top+1 cmds. Players are // limited to QUEUE_QUOTA. -mnp // a = QueueMax(Owner(executor)); if (a_Queue(Owner(executor), 1) > a) { a_Queue(Owner(executor), -1); notify(Owner(executor), "Run away objects: too many commands queued. Halted."); halt_que(Owner(executor), NOTHING); // Halt also means no command execution allowed. // s_Halted(executor); return NULL; } // We passed all the tests. // // Calculate the length of the save string. // size_t tlen = 0; static size_t nCommand; static size_t nLenEnv[NUM_ENV_VARS]; if (command) { nCommand = strlen(command) + 1; tlen = nCommand; } if (nargs > NUM_ENV_VARS) { nargs = NUM_ENV_VARS; } for (a = 0; a < nargs; a++) { if (args[a]) { nLenEnv[a] = strlen(args[a]) + 1; tlen += nLenEnv[a]; } } // Create the qeue entry and load the save string. // BQUE *tmp = alloc_qentry("setup_que.qblock"); tmp->comm = NULL; char *tptr = tmp->text = (char *)MEMALLOC(tlen); ISOUTOFMEMORY(tptr); if (command) { memcpy(tptr, command, nCommand); tmp->comm = tptr; tptr += nCommand; } for (a = 0; a < nargs; a++) { if (args[a]) { memcpy(tptr, args[a], nLenEnv[a]); tmp->env[a] = tptr; tptr += nLenEnv[a]; } else { tmp->env[a] = NULL; } } for ( ; a < NUM_ENV_VARS; a++) { tmp->env[a] = NULL; } if (sargs) { for (a = 0; a < MAX_GLOBAL_REGS; a++) { tmp->scr[a] = sargs[a]; if (sargs[a]) { RegAddRef(sargs[a]); } } } else { for (a = 0; a < MAX_GLOBAL_REGS; a++) { tmp->scr[a] = NULL; } } // Load the rest of the queue block. // tmp->executor = executor; tmp->IsTimed = false; tmp->sem = NOTHING; tmp->attr = 0; tmp->enactor = enactor; tmp->caller = caller; tmp->eval = eval; tmp->nargs = nargs; return tmp; }