/* * * 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. * */ #ifndef QPID_LINEARSTORE_JOURNALIMPL_H #define QPID_LINEARSTORE_JOURNALIMPL_H #include #include "qpid/broker/PersistableQueue.h" #include "qpid/linearstore/journal/aio_callback.h" #include "qpid/linearstore/journal/jcntl.h" #include "qpid/linearstore/PreparedTransaction.h" #include "qpid/sys/Timer.h" #include "qmf/org/apache/qpid/linearstore/Journal.h" namespace qpid{ namespace sys { //class Timer; } namespace linearstore{ namespace journal { // class EmptyFilePool; } class JournalImpl; class JournalLogImpl; class InactivityFireEvent : public qpid::sys::TimerTask { JournalImpl* _parent; qpid::sys::Mutex _ife_lock; public: InactivityFireEvent(JournalImpl* p, const qpid::sys::Duration timeout); virtual ~InactivityFireEvent() {} void fire(); inline void cancel() { qpid::sys::Mutex::ScopedLock sl(_ife_lock); _parent = 0; } }; class GetEventsFireEvent : public qpid::sys::TimerTask { JournalImpl* _parent; qpid::sys::Mutex _gefe_lock; public: GetEventsFireEvent(JournalImpl* p, const qpid::sys::Duration timeout); virtual ~GetEventsFireEvent() {} void fire(); inline void cancel() { qpid::sys::Mutex::ScopedLock sl(_gefe_lock); _parent = 0; } }; class JournalImpl : public qpid::broker::ExternalQueueStore, public qpid::linearstore::journal::jcntl, public qpid::linearstore::journal::aio_callback { public: typedef boost::function DeleteCallback; protected: qpid::sys::Timer& timer; JournalLogImpl& _journalLogRef; bool getEventsTimerSetFlag; boost::intrusive_ptr getEventsFireEventsPtr; qpid::sys::Mutex _getf_lock; qpid::sys::Mutex _read_lock; bool writeActivityFlag; bool flushTriggeredFlag; boost::intrusive_ptr inactivityFireEventPtr; qpid::management::ManagementAgent* _agent; qmf::org::apache::qpid::linearstore::Journal::shared_ptr _mgmtObject; DeleteCallback deleteCallback; public: JournalImpl(qpid::sys::Timer& timer, const std::string& journalId, const std::string& journalDirectory, JournalLogImpl& journalLogRef, const qpid::sys::Duration getEventsTimeout, const qpid::sys::Duration flushTimeout, qpid::management::ManagementAgent* agent, DeleteCallback deleteCallback=DeleteCallback() ); virtual ~JournalImpl(); void initManagement(qpid::management::ManagementAgent* agent); void initialize(qpid::linearstore::journal::EmptyFilePool* efp, const uint16_t wcache_num_pages, const uint32_t wcache_pgsize_sblks, qpid::linearstore::journal::aio_callback* const cbp); inline void initialize(qpid::linearstore::journal::EmptyFilePool* efpp, const uint16_t wcache_num_pages, const uint32_t wcache_pgsize_sblks) { initialize(efpp, wcache_num_pages, wcache_pgsize_sblks, this); } void recover(boost::shared_ptr efpm, const uint16_t wcache_num_pages, const uint32_t wcache_pgsize_sblks, qpid::linearstore::journal::aio_callback* const cbp, boost::ptr_list* prep_tx_list_ptr, uint64_t& highest_rid, uint64_t queue_id); inline void recover(boost::shared_ptr efpm, const uint16_t wcache_num_pages, const uint32_t wcache_pgsize_sblks, boost::ptr_list* prep_tx_list_ptr, uint64_t& highest_rid, uint64_t queue_id) { recover(efpm, wcache_num_pages, wcache_pgsize_sblks, this, prep_tx_list_ptr, highest_rid, queue_id); } void recover_complete(); // Overrides for write inactivity timer void enqueue_data_record(const void* const data_buff, const size_t tot_data_len, const size_t this_data_len, qpid::linearstore::journal::data_tok* dtokp, const bool transient = false); void enqueue_extern_data_record(const size_t tot_data_len, qpid::linearstore::journal::data_tok* dtokp, const bool transient = false); void enqueue_txn_data_record(const void* const data_buff, const size_t tot_data_len, const size_t this_data_len, qpid::linearstore::journal::data_tok* dtokp, const std::string& xid, const bool transient = false); void enqueue_extern_txn_data_record(const size_t tot_data_len, qpid::linearstore::journal::data_tok* dtokp, const std::string& xid, const bool transient = false); void dequeue_data_record(qpid::linearstore::journal::data_tok* const dtokp, const bool txn_coml_commit = false); void dequeue_txn_data_record(qpid::linearstore::journal::data_tok* const dtokp, const std::string& xid, const bool txn_coml_commit = false); void txn_abort(qpid::linearstore::journal::data_tok* const dtokp, const std::string& xid); void txn_commit(qpid::linearstore::journal::data_tok* const dtokp, const std::string& xid); void stop(bool block_till_aio_cmpl = false); // Overrides for get_events timer qpid::linearstore::journal::iores flush(const bool block_till_aio_cmpl = false); // TimerTask callback void getEventsFire(); void flushFire(); // AIO callbacks virtual void wr_aio_cb(std::vector& dtokl); virtual void rd_aio_cb(std::vector& pil); qpid::management::ManagementObject::shared_ptr GetManagementObject (void) const { return _mgmtObject; } qpid::management::Manageable::status_t ManagementMethod (uint32_t, qpid::management::Args&, std::string&); void resetDeleteCallback() { deleteCallback = DeleteCallback(); } protected: void createStore(); inline void setGetEventTimer() { getEventsFireEventsPtr->setupNextFire(); timer.add(getEventsFireEventsPtr); getEventsTimerSetFlag = true; } void handleIoResult(const qpid::linearstore::journal::iores r); // Management instrumentation callbacks overridden from jcntl inline void instr_incr_outstanding_aio_cnt() { if (_mgmtObject.get() != 0) _mgmtObject->inc_outstandingAIOs(); } inline void instr_decr_outstanding_aio_cnt() { if (_mgmtObject.get() != 0) _mgmtObject->dec_outstandingAIOs(); } }; // class JournalImpl class TplJournalImpl : public JournalImpl { public: TplJournalImpl(qpid::sys::Timer& timer, const std::string& journalId, const std::string& journalDirectory, JournalLogImpl& journalLogRef, const qpid::sys::Duration getEventsTimeout, const qpid::sys::Duration flushTimeout, qpid::management::ManagementAgent* agent) : JournalImpl(timer, journalId, journalDirectory, journalLogRef, getEventsTimeout, flushTimeout, agent) {} virtual ~TplJournalImpl() {} // Special version of read_data_record that ignores transactions - needed when reading the TPL inline qpid::linearstore::journal::iores read_data_record(void** const datapp, std::size_t& dsize, void** const xidpp, std::size_t& xidsize, bool& transient, bool& external, qpid::linearstore::journal::data_tok* const dtokp) { return JournalImpl::read_data_record(datapp, dsize, xidpp, xidsize, transient, external, dtokp, true); } }; // class TplJournalImpl } // namespace msgstore } // namespace mrg #endif // ifndef QPID_LINEARSTORE_JOURNALIMPL_H