/************************************************************************************************* * 功能:线程/ISR尝试向消息队列中发送消息 * * 参数:(1) pMsgQue 消息队列的地址 * * (2) pMsg2 保存消息结构地址的指针变量 * * (3) type 消息类型 * * (4) pHiRP 是否需要线程调度标记 * * (5) pError 详细调用结果 * * 返回: (1) eFailure 操作失败 * * (2) eSuccess 操作成功 * * 说明: * *************************************************************************************************/ static TState SendMessage(TMsgQueue* pMsgQue, void** pMsg2, TMsgType type, TBool* pHiRP, TError* pError) { TState state = eSuccess; TError error = IPC_ERR_NONE; TIpcContext* pContext = (TIpcContext*)0; /* 检查消息队列状态,如果消息队列满则返回失败 */ if (pMsgQue->Status == eMQFull) { error = IPC_ERR_INVALID_STATUS; state = eFailure; } else if (pMsgQue->Status == eMQEmpty) { /* 尝试唤醒写阻塞队列中的一个线程 */ if (pMsgQue->Property & IPC_PROP_PRIMQ_AVAIL) { pContext = (TIpcContext*)(pMsgQue->Queue.PrimaryHandle->Owner); } /* 在消息队列为空的情况下,如果队列中有线程等待,则说明是读阻塞队列, 保持消息队列状态不变 */ if (pContext != (TIpcContext*)0) { uIpcUnblockThread(pContext, eSuccess, IPC_ERR_NONE, pHiRP); /* 将消息发送给该线程 */ *(pContext->Data.Addr2) = *pMsg2; } else { /* 将线程发送的消息写入消息队列 */ SaveMessage(pMsgQue, pMsg2, type); pMsgQue->Status = (pMsgQue->Tail == pMsgQue->Head) ? eMQFull : eMQPartial; } } else /* if (mq->Status == eMQPartial) */ { /* 将线程发送的消息写入消息队列 */ SaveMessage(pMsgQue, pMsg2, type); /* 消息队列空的情况,如果是消息队列的容量是1,那么它的状态从空直接到 eMQFull, 否则消息队列进入 eMQPartial 状态 */ /* 消息队列普通的情况,消息对列写操作可能导致消息队列进入 eMQFull 状态或者保持 eMQPartial 状态 */ pMsgQue->Status = (pMsgQue->Tail == pMsgQue->Head) ? eMQFull : eMQPartial; } *pError = error; return state; }
//保存信息 VOID CSkinRichEdit::OnSaveString() { //保存信息 SaveMessage(NULL); return; }
// check and see if the message needs saving, and whether to ditch it or not bool AwayEditorWindow::CheckMessage() { if( !hasSelection ) return true; BAlert* alert; if( isDirty || genView->textview->IsDirty() ) { alert = new BAlert("", Language.get("AME_SAVE_CHANGES"), Language.get("CANCEL_LABEL"), Language.get("IGNORE_LABEL"), Language.get("SAVE_LABEL"), B_WIDTH_AS_USUAL, B_OFFSET_SPACING, B_WARNING_ALERT); alert->SetShortcut( 0, B_ESCAPE ); int32 index = alert->Go(); if( index == 2 ) if( SaveMessage() ) return true; else return false; if( index == 1 ) { if( currentMsg == BString(Language.get("AME_NEW_MESSAGE")) ) DeleteMessage(); } if( index == 0 ) { Revert(); return false; } } return true; }
void AwayEditorWindow::MessageReceived(BMessage* message) { switch(message->what) { case AWAY_NEW: NewMessage(); break; case AWAY_SAVE: SaveMessage(); break; case AWAY_DELETE: DeleteMessage(); break; case AWAY_CHANGED: isDirty = true; break; case BEAIM_RELOAD_PREF_SETTINGS: enterIsNewline = prefs->ReadBool( "EnterInsertsNewline", false ); tabIsTab = prefs->ReadBool( "TabIsTab", false ); break; case AWAY_SELECTED: { AwayItem* item = (AwayItem*)genView->listview->ItemAt( genView->listview->CurrentSelection() ); if( !item || !CheckMessage() ) { EnableMessageStuff(false); return; } LoadMessage( item->GetName() ); break; } case BEAIM_REFRESH_LANG_STRINGS: RefreshLangStrings(); break; default: BWindow::MessageReceived(message); } }
/* 处理消息队列读数据的情况 (1) 处理消息队列为满的情况:如果是容量是1的消息队列,读取操作会导致消息队列状态从满直接到空, 否则消息队列进入 eMQPartial 状态 (2) 处理消息队列普通的情况:如果消息队列中只有1个消息,对列读取操作可能导致消息队列进入空状态 否则消息队列保持 eMQPartial 状态 (3) 无论是消息队列满还是消息队列普通状态:最终状态只有普通和空。 */ static TState ReceiveMessage(TMsgQueue* pMsgQue, void** pMsg2, TBool* pHiRP, TError* pError) { TState state = eSuccess; TError error = IPC_ERR_NONE; TMsgType type; TIpcContext* pContext = (TIpcContext*)0; /* 检查消息队列状态 */ if (pMsgQue->Status == eMQEmpty) { error = IPC_ERR_INVALID_STATUS; state = eFailure; } else if (pMsgQue->Status == eMQFull) { /* 从消息队列中读取一个消息给当前线程 */ ConsumeMessage(pMsgQue, pMsg2); /* * 在消息队列满并且有线程阻塞在写队列中的情况下, * 需要将合适的线程接触阻塞并且将该线程携带的消息写入队列, * 所以保持消息队列状态不变 */ if (pMsgQue->Property & IPC_PROP_AUXIQ_AVAIL) { pContext = (TIpcContext*)(pMsgQue->Queue.AuxiliaryHandle->Owner); } else { if (pMsgQue->Property & IPC_PROP_PRIMQ_AVAIL) { pContext = (TIpcContext*)(pMsgQue->Queue.PrimaryHandle->Owner); } } if (pContext != (TIpcContext*)0) { uIpcUnblockThread(pContext, eSuccess, IPC_ERR_NONE, pHiRP); /* 根据线程所处的分队列判断消息类型 */ type = ((pContext->Option) & IPC_OPT_UARGENT) ? eUrgentMessage : eNormalMessage; /* 并且将该线程发送的消息写入消息队列 */ SaveMessage(pMsgQue, pContext->Data.Addr2, type); } else { pMsgQue->Status = (pMsgQue->Tail == pMsgQue->Head) ? eMQEmpty : eMQPartial; } } else /* if (mq->Status == eMQPartial) */ { /* 从消息队列中读取一个消息给当前线程 */ ConsumeMessage(pMsgQue, pMsg2); pMsgQue->Status = (pMsgQue->Tail == pMsgQue->Head) ? eMQEmpty : eMQPartial; } *pError = error; return state; }