EXPORT TINT hal_abortio(struct THALBase *hal, struct TTimeRequest *req) { struct HALSpecific *hws = hal->hmb_Specific; TAPTR exec = hws->hsp_ExecBase; TUINT status; #ifdef USE_MMTIMER EnterCriticalSection(&hws->hsp_DevLock); status = TExecGetMsgStatus(exec, req); if (status == (TMSG_STATUS_SENT | TMSGF_QUEUED)) { /* enforce immediate expiration */ req->ttr_Data.ttr_Time.tdt_Int64 = 0; req->ttr_Req.io_Error = TIOERR_ABORTED; TRemove(&req->ttr_Req.io_Node); while (!hal_replytimereq(req)); } LeaveCriticalSection(&hws->hsp_DevLock); #else EnterCriticalSection(&hws->hsp_DevLock); status = TExecGetMsgStatus(exec, req); if (!(status & TMSGF_RETURNED)) { if (status & TMSGF_QUEUED) { /* remove from ioport */ TAPTR ioport = TExecGetUserPort(exec, hws->hsp_DevTask); TExecRemoveMsg(exec, ioport, req); } else { /* remove from reqlist */ TRemove((struct TNode *) req); TExecSignal(exec, hws->hsp_DevTask, TTASK_SIG_USER); } } else { /* already replied */ req = TNULL; } LeaveCriticalSection(&hws->hsp_DevLock); if (req) { req->ttr_Req.io_Error = TIOERR_ABORTED; TExecReplyMsg(exec, req); } #endif return 0; }
static void TTASKENTRY hal_devfunc(struct TTask *task) { TAPTR exec = TGetExecBase(task); struct THALBase *hal = TExecGetHALBase(exec); struct HALSpecific *hps = hal->hmb_Specific; struct HALThread *thread = TlsGetValue(hps->hsp_TLSIndex); TAPTR port = TExecGetUserPort(exec, task); struct TTimeRequest *msg; TUINT sig = 0; TTIME waittime, curtime; struct TNode *nnode, *node; waittime.ttm_Sec = 2000000000; waittime.ttm_USec = 0; for (;;) { sig = hal_timedwaitevent(hal, thread, &waittime, TTASK_SIG_ABORT | TTASK_SIG_USER); if (sig & TTASK_SIG_ABORT) break; EnterCriticalSection(&hps->hsp_DevLock); hal_getsystime(hal, &curtime); while ((msg = TExecGetMsg(exec, port))) { TAddTime(&msg->ttr_Data.ttr_Time, &curtime); TAddTail(&hps->hsp_ReqList, (struct TNode *) msg); } waittime.ttm_Sec = 2000000000; waittime.ttm_USec = 0; node = hps->hsp_ReqList.tlh_Head; for (; (nnode = node->tln_Succ); node = nnode) { struct TTimeRequest *tr = (struct TTimeRequest *) node; TTIME *tm = &tr->ttr_Data.ttr_Time; if (TCmpTime(&curtime, tm) >= 0) { TRemove(node); tr->ttr_Req.io_Error = 0; TExecReplyMsg(exec, node); continue; } if (TCmpTime(tm, &waittime) < 0) waittime = *tm; } LeaveCriticalSection(&hps->hsp_DevLock); } TDBPRINTF(2,("goodbye from HAL device\n")); }
EXPORT void hal_beginio(struct THALBase *hal, struct TTimeRequest *req) { struct HALSpecific *hws = hal->hmb_Specific; TAPTR exec = hws->hsp_ExecBase; TTIME curtime; TINT64 x = 0; switch (req->ttr_Req.io_Command) { /* execute asynchronously */ case TTREQ_WAITLOCALDATE: /* microseconds west of GMT: */ x = hal_getdstfromlocaldate(hal, &req->ttr_Data.ttr_Date); x *= 1000000; case TTREQ_WAITUNIVERSALDATE: x += req->ttr_Data.ttr_Date.tdt_Int64; x -= 11644473600000000ULL; req->ttr_Data.ttr_Date.tdt_Int64 = x; #ifndef USE_MMTIMER hal_getsystime(hal, &curtime); TSubTime(&req->ttr_Data.ttr_Time, &curtime); #endif goto addtimereq; case TTREQ_WAITTIME: #ifdef USE_MMTIMER hal_getsystime(hal, &curtime); TAddTime(&req->ttr_Data.ttr_Time, &curtime); #endif addtimereq: { #ifdef USE_MMTIMER struct TMessage *msg = TGETMSGPTR(req); EnterCriticalSection(&hws->hsp_DevLock); msg->tmsg_Flags = TMSG_STATUS_SENT | TMSGF_QUEUED; msg->tmsg_RPort = req->ttr_Req.io_ReplyPort; TAddTail(&hws->hsp_ReqList, (struct TNode *) req); LeaveCriticalSection(&hws->hsp_DevLock); #else TExecPutMsg(exec, TExecGetUserPort(exec, hws->hsp_DevTask), req->ttr_Req.io_ReplyPort, req); #endif return; } /* execute synchronously */ default: case TTREQ_GETUNIVERSALDATE: { TINT timezone_bias; hal_getsysdate(hal, &req->ttr_Data.ttr_Date, &timezone_bias); break; } case TTREQ_GETLOCALDATE: hal_getsysdate(hal, &req->ttr_Data.ttr_Date, TNULL); break; case TTREQ_GETSYSTEMTIME: hal_getsystime(hal, &req->ttr_Data.ttr_Time); break; #if 0 case TTREQ_GETDSFROMDATE: req->ttr_Data.ttr_DSSec = hal_dsfromdate(hal, &req->ttr_Data.ttr_Date.ttr_Date); break; #endif } req->ttr_Req.io_Error = 0; if (!(req->ttr_Req.io_Flags & TIOF_QUICK)) { /* async operation indicated; reply to self */ TExecReplyMsg(exec, req); } }