| /* $Id$ |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to you under the Apache License, Version |
| * 2.0 (the "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| #include "support/EtchPlainMailbox.h" |
| |
| EtchPlainMailbox::EtchPlainMailbox(EtchMailboxManager* mailboxManager, EtchLong messageId) |
| : mMailboxManager(mailboxManager), mNotify(NULL), mState(NULL), mMessageId(messageId), mQueue(1) { |
| } |
| |
| EtchPlainMailbox::~EtchPlainMailbox() { |
| while (!mQueue.isEmpty()) { |
| EtchMailbox::EtchElement* element = NULL; |
| if(ETCH_OK == mQueue.get(&element)) { |
| delete element; |
| } |
| } |
| } |
| |
| EtchMailboxManager* EtchPlainMailbox::getMailboxManager() { |
| return mMailboxManager; |
| } |
| |
| EtchLong EtchPlainMailbox::getMessageId() { |
| return mMessageId; |
| } |
| |
| status_t EtchPlainMailbox::message(capu::SmartPointer<EtchWho> sender, capu::SmartPointer<EtchMessage> msg) { |
| status_t status; |
| EtchMailbox::EtchElement* element = new EtchMailbox::EtchElement(sender, msg); |
| |
| mMutex.lock(); |
| status = mQueue.put(element, -1); |
| mMutex.unlock(); |
| |
| if(status == ETCH_OK) { |
| fireNotify(); |
| return ETCH_OK; |
| } else { |
| // TODO: log error if message could not be put to the mailbox |
| delete element; |
| return ETCH_ERROR; |
| } |
| } |
| |
| void EtchPlainMailbox::fireNotify() { |
| |
| EtchMailbox::EtchNotify *n; |
| EtchObject* s; |
| capu::bool_t c; |
| |
| mMutex.lock(); |
| n = mNotify; |
| s = mState; |
| c = mQueue.isClosed(); |
| |
| if (n != NULL) { |
| n->mailboxStatus(this, s, c); |
| } |
| mMutex.unlock(); |
| } |
| |
| status_t EtchPlainMailbox::read(EtchMailbox::EtchElement*& result) { |
| mMutex.lock(); |
| status_t status = mQueue.get(&result); |
| mMutex.unlock(); |
| if(ETCH_OK == status) { |
| return ETCH_OK; |
| } |
| // TODO: logging |
| return ETCH_ERROR; |
| } |
| |
| status_t EtchPlainMailbox::read(EtchMailbox::EtchElement *& result, capu::int32_t maxDelay) { |
| mMutex.lock(); |
| status_t status = mQueue.get(&result, maxDelay); |
| mMutex.unlock(); |
| if(status == ETCH_OK) { |
| return ETCH_OK; |
| } |
| return ETCH_ERROR; |
| } |
| |
| status_t EtchPlainMailbox::closeDelivery(capu::bool_t withNotification) { |
| |
| mMutex.lock(); |
| if(mQueue.isClosed()) { |
| mMutex.unlock(); |
| return ETCH_EINVAL; |
| } |
| |
| mMailboxManager->unregisterMailbox(getMessageId()); |
| mQueue.close(); |
| mMutex.unlock(); |
| |
| if (withNotification) { |
| fireNotify(); |
| } |
| |
| return ETCH_OK; |
| } |
| |
| status_t EtchPlainMailbox::closeRead() { |
| if (closeDelivery(false) == ETCH_OK) { |
| EtchMailbox::EtchElement* mbe = NULL; |
| while ((read(mbe)) == ETCH_OK) { |
| mMailboxManager->redeliver(mbe->mSender, mbe->mMsg); |
| delete mbe; |
| } |
| return ETCH_OK; |
| } |
| return ETCH_ERROR; |
| } |
| |
| status_t EtchPlainMailbox::registerNotify(EtchMailbox::EtchNotify* notify, EtchObject* state, capu::int32_t maxDelay) { |
| if(notify == NULL) { |
| return ETCH_EINVAL; |
| } |
| |
| if(maxDelay < 0) { |
| return ETCH_EINVAL; |
| } |
| |
| capu::bool_t isNotEmptyOrIsClosed; |
| |
| mMutex.lock(); |
| |
| if(mNotify != NULL) { |
| mMutex.unlock(); |
| return ETCH_EINVAL; |
| } |
| |
| mNotify = notify; |
| mState = state; |
| |
| isNotEmptyOrIsClosed = !mQueue.isEmpty() || mQueue.isClosed(); |
| |
| mMutex.unlock(); |
| |
| if(isNotEmptyOrIsClosed) { |
| fireNotify(); |
| } |
| |
| return ETCH_OK; |
| } |
| |
| status_t EtchPlainMailbox::unregisterNotify(EtchMailbox::EtchNotify* notify) { |
| |
| if(mNotify == NULL) { |
| return ETCH_EINVAL; |
| } |
| |
| if(notify == NULL) { |
| return ETCH_OK; |
| } |
| |
| mMutex.lock(); |
| |
| if(mNotify != notify) { |
| mMutex.unlock(); |
| return ETCH_EINVAL; |
| } |
| |
| mNotify = NULL; |
| mState = NULL; |
| |
| mMutex.unlock(); |
| |
| return ETCH_OK; |
| } |
| |
| capu::bool_t EtchPlainMailbox::isEmpty() { |
| capu::bool_t res = mQueue.isEmpty(); |
| return res; |
| } |
| |
| capu::bool_t EtchPlainMailbox::isClosed() { |
| capu::bool_t res = mQueue.isClosed(); |
| return res; |
| } |
| |
| capu::bool_t EtchPlainMailbox::isFull() { |
| capu::bool_t res = mQueue.isFull(); |
| return res; |
| } |