/* * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. * */ #ifndef SHARE_LOGGING_ASYNC_FLUSHER_HPP #define SHARE_LOGGING_ASYNC_FLUSHER_HPP #include "memory/resourceArea.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/task.hpp" #include "utilities/linkedlist.hpp" #include "utilities/pair.hpp" template class LinkedListFIFO : private LinkedListImpl { private: LinkedListNode* _tail; // this is not a generic FIFO, template parameter is only for testing. public: LinkedListFIFO() : _tail(NULL) {} void push(const E& e) { if (!_tail) _tail = this->add(e); else _tail = this->insert_after(e, _tail); } void pop_all(LinkedList* logs) { logs->move(static_cast* >(this)); _tail = NULL; } }; class LogMessageBuffer; class LogTagSet; class AsyncLogMessage : private Pair { AsyncLogMessage(LogTagSet* t, LogMessageBuffer* b) : Pair(t, b) {} public: static AsyncLogMessage create(LogTagSet* t, LogMessageBuffer* b) { return AsyncLogMessage(t, b); } bool equals(const AsyncLogMessage& o) const { return first == o.first && second == o.second; } LogTagSet* tagset() { return first; } LogMessageBuffer* buffer() { return second; } }; typedef LinkedListFIFO AsyncLogFIFO; class LogAsyncFlusher : public PeriodicTask { friend class AsyncLogTest_flusher_test_vm_Test; private: static LogAsyncFlusher* _instance; Mutex _lock; AsyncLogFIFO _fifo; LogAsyncFlusher(size_t interval/*ms*/) : PeriodicTask(interval), _lock(Mutex::tty, "logAsyncFlusher", Mutex::_allow_vm_block_flag, Mutex::_safepoint_check_never) { this->enroll(); } ~LogAsyncFlusher(); public: void enqueue(LogTagSet* tagset, LogMessageBuffer* buf); virtual void task(); void flush() { task(); } // none of following functions are thread-safe. // Meyer's singleton is not thread-safe until C++11. static void initialize(); static void cleanup(); static LogAsyncFlusher* instance(); }; #endif // SHARE_LOGGING_ASYNC_FLUSHER_HPP