Serenity Operating System
at master 69 lines 1.7 kB view raw
1/* 2 * Copyright (c) 2021, the SerenityOS developers. 3 * Copyright (c) 2021, Andreas Kling <kling@serenityos.org> 4 * 5 * SPDX-License-Identifier: BSD-2-Clause 6 */ 7 8#pragma once 9 10#include <AK/Error.h> 11#include <AK/IntrusiveList.h> 12#include <Kernel/Forward.h> 13#include <Kernel/Locking/SpinlockProtected.h> 14#include <Kernel/WaitQueue.h> 15 16namespace Kernel { 17 18extern WorkQueue* g_io_work; 19extern WorkQueue* g_ata_work; 20 21class WorkQueue { 22 AK_MAKE_NONCOPYABLE(WorkQueue); 23 AK_MAKE_NONMOVABLE(WorkQueue); 24 25public: 26 static void initialize(); 27 28 ErrorOr<void> try_queue(void (*function)(void*), void* data = nullptr, void (*free_data)(void*) = nullptr) 29 { 30 auto item = new (nothrow) WorkItem; // TODO: use a pool 31 if (!item) 32 return Error::from_errno(ENOMEM); 33 item->function = [function, data, free_data] { 34 function(data); 35 if (free_data) 36 free_data(data); 37 }; 38 do_queue(*item); 39 return {}; 40 } 41 42 template<typename Function> 43 ErrorOr<void> try_queue(Function function) 44 { 45 auto item = new (nothrow) WorkItem; // TODO: use a pool 46 if (!item) 47 return Error::from_errno(ENOMEM); 48 item->function = Function(function); 49 do_queue(*item); 50 return {}; 51 } 52 53private: 54 explicit WorkQueue(StringView); 55 56 struct WorkItem { 57 public: 58 IntrusiveListNode<WorkItem> m_node; 59 Function<void()> function; 60 }; 61 62 void do_queue(WorkItem&); 63 64 LockRefPtr<Thread> m_thread; 65 WaitQueue m_wait_queue; 66 SpinlockProtected<IntrusiveList<&WorkItem::m_node>, LockRank::None> m_items {}; 67}; 68 69}