Compare commits

..

13 Commits

Author SHA1 Message Date
d49fbb8016
apps: Add socket client
All checks were successful
continuous-integration/drone/pr Build is passing
2023-07-28 17:31:27 +02:00
8b91b7acc0
libc: Add wrappers for listen(), connect(), and accept() 2023-07-28 17:30:59 +02:00
ec5b83ff01
libluna: Add a few more network-related errno codes 2023-07-28 17:30:35 +02:00
be5903c0c8
kernel: Implement listen(), connect() and accept() 2023-07-28 17:30:20 +02:00
d4fc002d8a
libluna: Add a variant of CircularQueue that dynamically allocates its buffer at runtime
This is needed to implement the backlog queue for listening sockets.
2023-07-28 17:28:18 +02:00
97d7a7cc6b
kernel: Use a did_close callback for UnixSockets
All checks were successful
continuous-integration/drone/pr Build is passing
2023-07-27 19:21:46 +02:00
b77b72a551
kernel: Separate FileDescriptors and OpenFileDescription
Also, add a did_close() callback for OpenFileDescriptions losing all their references.
2023-07-27 19:21:23 +02:00
12c2577181
apps: Add socket-test
All checks were successful
continuous-integration/drone/pr Build is passing
2023-07-27 16:37:17 +02:00
ca3f3fbe16
kernel+libc: Add basic Unix sockets (creation and binding) 2023-07-27 16:37:10 +02:00
c819a0cfc1
kernel: Add functionality to allow external inodes (such as sockets) to acquire an inode number from a file system
This is only implemented in tmpfs.
2023-07-27 16:36:36 +02:00
1b596027c1
kernel+libluna: Add Buffer::dequeue_data() 2023-07-27 16:35:52 +02:00
48f5f6ea33
kernel+libc+libos: Add inode type for sockets 2023-07-27 16:35:27 +02:00
27fcdab85f
libluna: Add new socket-related errno codes 2023-07-27 16:31:57 +02:00
9 changed files with 63 additions and 107 deletions

View File

@ -131,7 +131,7 @@ namespace ATA
static constexpr u16 END_OF_PRDT = (1 << 15); static constexpr u16 END_OF_PRDT = (1 << 15);
class Drive : public Shareable class Drive
{ {
public: public:
Drive(Channel* channel, u8 drive_index, Badge<Channel>); Drive(Channel* channel, u8 drive_index, Badge<Channel>);
@ -274,7 +274,7 @@ namespace ATA
SharedPtr<Drive> m_drives[2]; SharedPtr<Drive> m_drives[2];
}; };
class Controller : public Shareable class Controller
{ {
public: public:
static Result<void> scan(); static Result<void> scan();

View File

@ -6,7 +6,7 @@ class PipeInodeBase;
class PipeReader; class PipeReader;
class PipeWriter; class PipeWriter;
class Pipe : public Shareable class Pipe
{ {
public: public:
static Result<void> create(SharedPtr<VFS::Inode>& rpipe, SharedPtr<VFS::Inode>& wpipe); static Result<void> create(SharedPtr<VFS::Inode>& rpipe, SharedPtr<VFS::Inode>& wpipe);

View File

@ -22,7 +22,7 @@ namespace VFS
class Inode; class Inode;
class FileSystem : public Shareable class FileSystem
{ {
public: public:
virtual SharedPtr<Inode> root_inode() const = 0; virtual SharedPtr<Inode> root_inode() const = 0;
@ -79,7 +79,7 @@ namespace VFS
StaticString<128> name; StaticString<128> name;
}; };
class Inode : public Shareable class Inode
{ {
public: public:
virtual Result<u64> ioctl(int, void*) virtual Result<u64> ioctl(int, void*)

View File

@ -1,9 +1,8 @@
#pragma once #pragma once
#include "Log.h" #include "Log.h"
#include <luna/Result.h> #include <luna/Result.h>
#include <luna/SharedPtr.h>
class Device : public Shareable class Device
{ {
public: public:
virtual Result<usize> read(u8* buf, usize offset, usize length) const = 0; virtual Result<usize> read(u8* buf, usize offset, usize length) const = 0;

View File

@ -5,76 +5,89 @@
#include <luna/OwnedPtr.h> #include <luna/OwnedPtr.h>
#include <luna/Result.h> #include <luna/Result.h>
#include <luna/ScopeGuard.h> #include <luna/ScopeGuard.h>
#include <luna/TypeTraits.h>
template <typename T> class SharedPtr; namespace __detail
template <typename T> SharedPtr<T> adopt_shared(T*);
struct Shareable
{ {
void ref() struct RefCount
{ {
m_ref_count++; void ref()
} {
m_ref_count++;
}
bool unref() bool unref()
{ {
m_ref_count--; m_ref_count--;
return m_ref_count == 0; return m_ref_count == 0;
} }
Atomic<int> m_ref_count { 1 }; private:
}; Atomic<int> m_ref_count { 1 };
};
}
template <typename T> class SharedPtr template <typename T> class SharedPtr
{ {
using RefCount = __detail::RefCount;
public: public:
SharedPtr() SharedPtr()
{ {
m_ptr = nullptr; m_ptr = nullptr;
m_ref_count = nullptr;
} }
SharedPtr(T* ptr) : m_ptr(ptr) SharedPtr(T* ptr, RefCount* ref_count) : m_ptr(ptr), m_ref_count(ref_count)
{ {
} }
SharedPtr(const SharedPtr<T>& other) : m_ptr(other.m_ptr) SharedPtr(const SharedPtr<T>& other) : m_ptr(other.m_ptr), m_ref_count(other.m_ref_count)
{ {
if (m_ptr) shareable()->ref(); if (m_ref_count) m_ref_count->ref();
} }
SharedPtr(SharedPtr<T>&& other) : m_ptr(other.m_ptr) SharedPtr(SharedPtr<T>&& other) : m_ptr(other.m_ptr), m_ref_count(other.m_ref_count)
{ {
other.m_ptr = nullptr; other.m_ptr = nullptr;
other.m_ref_count = nullptr;
} }
template <typename Tp> operator SharedPtr<Tp>() template <typename Tp> operator SharedPtr<Tp>()
{ {
if (m_ptr) shareable()->ref(); if (m_ref_count) m_ref_count->ref();
return { (Tp*)m_ptr }; return { (Tp*)m_ptr, m_ref_count };
} }
~SharedPtr() ~SharedPtr()
{ {
if (m_ptr && shareable()->unref()) { delete m_ptr; } if (m_ref_count && m_ref_count->unref())
{
delete m_ref_count;
delete m_ptr;
}
} }
SharedPtr<T>& operator=(const SharedPtr<T>& other) SharedPtr<T>& operator=(const SharedPtr<T>& other)
{ {
if (&other == this) return *this; if (&other == this) return *this;
if (m_ptr && shareable()->unref()) { delete m_ptr; } if (m_ref_count && m_ref_count->unref())
{
delete m_ref_count;
delete m_ptr;
}
m_ptr = other.m_ptr; m_ptr = other.m_ptr;
m_ref_count = other.m_ref_count;
if (m_ptr) shareable()->ref(); if (m_ref_count) m_ref_count->ref();
return *this; return *this;
} }
bool operator==(const SharedPtr<T>& other) bool operator==(const SharedPtr<T>& other)
{ {
return m_ptr == other.m_ptr; return m_ptr == other.m_ptr && m_ref_count == other.m_ref_count;
} }
T* ptr() const T* ptr() const
@ -99,17 +112,21 @@ template <typename T> class SharedPtr
private: private:
T* m_ptr; T* m_ptr;
RefCount* m_ref_count;
Shareable* shareable()
{
static_assert(IsBaseOf<Shareable, T>);
return (Shareable*)m_ptr;
}
}; };
template <typename T> SharedPtr<T> adopt_shared(T* ptr) // NOTE: ptr is deleted if any of the adopt_shared* functions fail to construct a SharedPtr.
template <typename T> Result<SharedPtr<T>> adopt_shared(T* ptr)
{ {
return SharedPtr<T> { ptr }; using RefCount = __detail::RefCount;
auto guard = make_scope_guard([ptr] { delete ptr; });
RefCount* const ref_count = TRY(make<RefCount>());
guard.deactivate();
return SharedPtr<T> { ptr, ref_count };
} }
template <typename T, class... Args> Result<SharedPtr<T>> make_shared(Args... args) template <typename T, class... Args> Result<SharedPtr<T>> make_shared(Args... args)
@ -125,10 +142,12 @@ template <typename T> Result<SharedPtr<T>> adopt_shared_if_nonnull(T* ptr)
return err(ENOMEM); return err(ENOMEM);
} }
template <typename T> SharedPtr<T> adopt_shared_from_owned(OwnedPtr<T>&& other) template <typename T> Result<SharedPtr<T>> adopt_shared_from_owned(OwnedPtr<T>&& other)
{ {
T* ptr = other.m_ptr; T* ptr = other.m_ptr;
other.m_ptr = nullptr; other.m_ptr = nullptr;
return SharedPtr<T> { ptr }; const SharedPtr<T> shared_ptr = TRY(adopt_shared(ptr));
return shared_ptr;
} }

View File

@ -19,7 +19,7 @@ namespace os
/** /**
* @brief An object-oriented directory handle, which is closed when all references to it go out of scope. * @brief An object-oriented directory handle, which is closed when all references to it go out of scope.
*/ */
class Directory : public Shareable class Directory
{ {
public: public:
/** /**

View File

@ -22,7 +22,7 @@ namespace os
/** /**
* @brief An object-oriented file handle, which is closed when all references to it go out of scope. * @brief An object-oriented file handle, which is closed when all references to it go out of scope.
*/ */
class File : public Shareable class File
{ {
public: public:
/** /**

View File

@ -5,7 +5,7 @@ target_include_directories(test PUBLIC ${LUNA_BASE}/usr/include)
function(luna_test SOURCE_FILE APP_NAME) function(luna_test SOURCE_FILE APP_NAME)
add_executable(${APP_NAME} ${SOURCE_FILE}) add_executable(${APP_NAME} ${SOURCE_FILE})
target_compile_options(${APP_NAME} PRIVATE -O0 ${COMMON_FLAGS} -fno-threadsafe-statics -Wno-write-strings) target_compile_options(${APP_NAME} PRIVATE -Os ${COMMON_FLAGS} -Wno-write-strings)
add_dependencies(${APP_NAME} libc) add_dependencies(${APP_NAME} libc)
target_include_directories(${APP_NAME} PRIVATE ${LUNA_BASE}/usr/include) target_include_directories(${APP_NAME} PRIVATE ${LUNA_BASE}/usr/include)
target_link_libraries(${APP_NAME} PRIVATE test os) target_link_libraries(${APP_NAME} PRIVATE test os)
@ -19,7 +19,6 @@ luna_test(libluna/TestUtf8.cpp TestUtf8)
luna_test(libluna/TestFormat.cpp TestFormat) luna_test(libluna/TestFormat.cpp TestFormat)
luna_test(libluna/TestHashTable.cpp TestHashTable) luna_test(libluna/TestHashTable.cpp TestHashTable)
luna_test(libluna/TestCPath.cpp TestCPath) luna_test(libluna/TestCPath.cpp TestCPath)
luna_test(libluna/TestSharedPtr.cpp TestSharedPtr)
luna_test(libc/TestScanf.cpp TestScanf) luna_test(libc/TestScanf.cpp TestScanf)
luna_test(libc/TestString.cpp TestString) luna_test(libc/TestString.cpp TestString)
luna_test(libc/TestEnv.cpp TestEnv) luna_test(libc/TestEnv.cpp TestEnv)

View File

@ -1,61 +0,0 @@
#include <luna/SharedPtr.h>
#include <test.h>
class SampleClass : public Shareable
{
public:
SampleClass(int* ptr, int value) : m_ptr(ptr), m_value(value)
{
}
~SampleClass()
{
if (m_ptr) *m_ptr = m_value;
}
private:
int* m_ptr;
int m_value;
};
TestResult test_shared_ptr_destroyed_on_scope_exit()
{
static int value = 0;
{
SharedPtr<SampleClass> sample = TRY(make_shared<SampleClass>(&value, 1));
}
validate(value == 1);
test_success;
}
TestResult test_shared_ptr_preserved_if_at_least_one_copy_exists()
{
static int value = 0;
static SharedPtr<SampleClass> ptr = {};
{
SharedPtr<SampleClass> sample = TRY(make_shared<SampleClass>(&value, 1));
ptr = sample;
}
validate(value == 0);
ptr = {};
validate(value == 1);
test_success;
}
Result<void> test_main()
{
test_prelude;
run_test(test_shared_ptr_destroyed_on_scope_exit);
run_test(test_shared_ptr_preserved_if_at_least_one_copy_exists);
return {};
}