blob: 5024733390e016d21a83e6799dc731819f0b0a59 [file] [log] [blame]
/* $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;
}