Skip to content

Commit

Permalink
Merge pull request ostis-dev#371 from NikitaZotov/feat/block_events
Browse files Browse the repository at this point in the history
[memory][context] Block events mode
  • Loading branch information
NikitaZotov authored Mar 18, 2024
2 parents a70a76c + b38a2a4 commit 304405e
Show file tree
Hide file tree
Showing 10 changed files with 223 additions and 6 deletions.
1 change: 1 addition & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Block events mode for sc-memory context
- Opportunity to set permissions for set of users
- Guests identification
- Create guest users during creating sc-memory context
Expand Down
5 changes: 4 additions & 1 deletion sc-memory/sc-core/sc-store/sc_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,10 @@ sc_result sc_event_emit(
if (ctx == null_ptr)
return SC_RESULT_NO;

if (_sc_memory_context_is_pending(ctx))
if (_sc_memory_context_are_events_blocking(ctx))
return SC_RESULT_OK;

if (_sc_memory_context_are_events_pending(ctx))
{
_sc_memory_context_pend_event(ctx, type, subscription_addr, connector_addr, connector_type, other_addr);
return SC_RESULT_OK;
Expand Down
10 changes: 10 additions & 0 deletions sc-memory/sc-core/sc_memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,16 @@ void sc_memory_context_pending_end(sc_memory_context * ctx)
_sc_memory_context_pending_end(ctx);
}

void sc_memory_context_blocking_begin(sc_memory_context * ctx)
{
_sc_memory_context_blocking_begin(ctx);
}

void sc_memory_context_blocking_end(sc_memory_context * ctx)
{
_sc_memory_context_blocking_end(ctx);
}

sc_bool sc_memory_is_initialized()
{
return sc_storage_is_initialized();
Expand Down
24 changes: 24 additions & 0 deletions sc-memory/sc-core/sc_memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,30 @@ _SC_EXTERN void sc_memory_context_pending_begin(sc_memory_context * ctx);
*/
_SC_EXTERN void sc_memory_context_pending_end(sc_memory_context * ctx);

/*!
* @brief Starts events blocking mode for a context.
*
* In this mode, all new emitted events will be blocking until `sc_memory_context_blocking_end` is called.
*
* @param ctx Pointer to the sc-memory context.
*
* @note Use this function to start a blocking mode for events emitted by the specified context.
* @see sc_memory_context_blocking_end
*/
_SC_EXTERN void sc_memory_context_blocking_begin(sc_memory_context * ctx);

/*!
* @brief Ends events blocking mode for a context.
*
* This function ends the blocking mode for events emitted by the specified context.
*
* @param ctx Pointer to the sc-memory context.
*
* @note Use this function to end the blocking mode for events emitted by the specified context.
* @see sc_memory_context_blocking_begin
*/
_SC_EXTERN void sc_memory_context_blocking_end(sc_memory_context * ctx);

/*!
* @brief Checks if sc-memory is initialized.
*
Expand Down
29 changes: 26 additions & 3 deletions sc-memory/sc-core/sc_memory_context_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ struct _sc_event_emit_params
};

#define SC_CONTEXT_FLAG_PENDING_EVENTS 0x1
#define SC_CONTEXT_FLAG_BLOCKING_EVENTS 0x2

#define SC_CONTEXT_PERMISSIONS_FULL 0xff

Expand Down Expand Up @@ -210,11 +211,11 @@ sc_addr _sc_memory_context_get_user_addr(sc_memory_context * ctx)
return user_addr;
}

sc_bool _sc_memory_context_is_pending(sc_memory_context const * ctx)
sc_bool _sc_memory_context_are_events_pending(sc_memory_context const * ctx)
{
sc_monitor_acquire_write((sc_monitor *)&ctx->monitor);
sc_monitor_acquire_read((sc_monitor *)&ctx->monitor);
sc_bool result = ((sc_memory_context *)ctx)->flags & SC_CONTEXT_FLAG_PENDING_EVENTS;
sc_monitor_release_write((sc_monitor *)&ctx->monitor);
sc_monitor_release_read((sc_monitor *)&ctx->monitor);
return result;
}

Expand Down Expand Up @@ -276,3 +277,25 @@ void _sc_memory_context_pending_end(sc_memory_context * ctx)
_sc_memory_context_emit_events(ctx);
sc_monitor_release_write(&ctx->monitor);
}

sc_bool _sc_memory_context_are_events_blocking(sc_memory_context const * ctx)
{
sc_monitor_acquire_read((sc_monitor *)&ctx->monitor);
sc_bool result = ((sc_memory_context *)ctx)->flags & SC_CONTEXT_FLAG_BLOCKING_EVENTS;
sc_monitor_release_read((sc_monitor *)&ctx->monitor);
return result;
}

void _sc_memory_context_blocking_begin(sc_memory_context * ctx)
{
sc_monitor_acquire_write(&ctx->monitor);
ctx->flags |= SC_CONTEXT_FLAG_BLOCKING_EVENTS;
sc_monitor_release_write(&ctx->monitor);
}

void _sc_memory_context_blocking_end(sc_memory_context * ctx)
{
sc_monitor_acquire_write(&ctx->monitor);
ctx->flags &= ~SC_CONTEXT_FLAG_BLOCKING_EVENTS;
sc_monitor_release_write(&ctx->monitor);
}
17 changes: 16 additions & 1 deletion sc-memory/sc-core/sc_memory_context_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ void _sc_memory_context_free_impl(sc_memory_context_manager * manager, sc_memory
sc_addr _sc_memory_context_get_user_addr(sc_memory_context * ctx);

//! Checks if specified sc-memory context has pending events block.
sc_bool _sc_memory_context_is_pending(sc_memory_context const * ctx);
sc_bool _sc_memory_context_are_events_pending(sc_memory_context const * ctx);

/*! Function that marks the beginning of a pending events block in a sc-memory context.
* @param ctx Pointer to the sc-memory context for which the pending events block begins.
Expand Down Expand Up @@ -126,4 +126,19 @@ void _sc_memory_context_pend_event(
*/
void _sc_memory_context_emit_events(sc_memory_context const * ctx);

//! Checks if specified sc-memory context has blocking events block.
sc_bool _sc_memory_context_are_events_blocking(sc_memory_context const * ctx);

/*! Function that marks the beginning of a blocking events block in a sc-memory context.
* @param ctx Pointer to the sc-memory context for which the blocking events block begins.
* @note This function marks the beginning of a blocking events block in the sc-memory context.
*/
void _sc_memory_context_blocking_begin(sc_memory_context * ctx);

/*! Function that marks the end of a blocking events block in a sc-memory context.
* @param ctx Pointer to the sc-memory context for which the blocking events block ends.
* @note This function marks the end of a blocking events block in the sc-memory context.
*/
void _sc_memory_context_blocking_end(sc_memory_context * ctx);

#endif
2 changes: 1 addition & 1 deletion sc-memory/sc-core/sc_memory_context_permissions.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

#include "sc_memory_context_manager.h"

#define SC_CONTEXT_FLAG_SYSTEM 0x2
#define SC_CONTEXT_FLAG_SYSTEM 0x10

/**
* @brief Sets permissions for a specific sc-memory element.
Expand Down
12 changes: 12 additions & 0 deletions sc-memory/sc-memory/sc_memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,18 @@ void ScMemoryContext::EndEventsPending()
sc_memory_context_pending_end(m_context);
}

void ScMemoryContext::BeingEventsBlocking()
{
CHECK_CONTEXT;
sc_memory_context_blocking_begin(m_context);
}

void ScMemoryContext::EndEventsBlocking()
{
CHECK_CONTEXT;
sc_memory_context_blocking_end(m_context);
}

bool ScMemoryContext::IsValid() const
{
return m_context != nullptr;
Expand Down
24 changes: 24 additions & 0 deletions sc-memory/sc-memory/sc_memory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,12 @@ class ScMemoryContext
//! End events pending mode
_SC_EXTERN void EndEventsPending();

//! Begin events blocking mode
_SC_EXTERN void BeingEventsBlocking();

//! End events blocking mode
_SC_EXTERN void EndEventsBlocking();

/*!
* @brief Checks if the sc-memory context is valid.
*
Expand Down Expand Up @@ -1240,3 +1246,21 @@ class ScMemoryContextEventsPendingGuard
private:
ScMemoryContext & m_ctx;
};

class ScMemoryContextEventsBlockingGuard
{
public:
_SC_EXTERN explicit ScMemoryContextEventsBlockingGuard(ScMemoryContext & ctx)
: m_ctx(ctx)
{
m_ctx.BeingEventsBlocking();
}

_SC_EXTERN ~ScMemoryContextEventsBlockingGuard()
{
m_ctx.EndEventsBlocking();
}

private:
ScMemoryContext & m_ctx;
};
105 changes: 105 additions & 0 deletions sc-memory/tests/sc-memory/events/test_sc_event.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -408,3 +408,108 @@ TEST_F(ScEventTest, pend_events)

EXPECT_EQ(passedCount, el_num);
}

TEST_F(ScEventTest, BlockEventsAndNotEmitAfter)
{
ScAddr const nodeAddr = m_ctx->CreateNode(ScType::NodeConst);

std::atomic_bool isCalled = false;
ScEventAddOutputEdge event(
*m_ctx,
nodeAddr,
[&isCalled](ScAddr const & addr, ScAddr const &, ScAddr const & target)
{
return isCalled = true;
});

m_ctx->BeingEventsBlocking();

ScAddr const nodeAddr2 = m_ctx->CreateNode(ScType::NodeConst);
m_ctx->CreateEdge(ScType::EdgeAccessConstPosPerm, nodeAddr, nodeAddr2);

m_ctx->EndEventsBlocking();

std::this_thread::sleep_for(std::chrono::milliseconds(10));
EXPECT_FALSE(isCalled);
}

TEST_F(ScEventTest, BlockEventsAndEmitAfter)
{
ScAddr const nodeAddr = m_ctx->CreateNode(ScType::NodeConst);

std::atomic_bool isCalled = false;
ScEventAddOutputEdge event(
*m_ctx,
nodeAddr,
[&isCalled](ScAddr const & addr, ScAddr const &, ScAddr const & target)
{
return isCalled = true;
});

m_ctx->BeingEventsBlocking();

ScAddr nodeAddr2 = m_ctx->CreateNode(ScType::NodeConst);
m_ctx->CreateEdge(ScType::EdgeAccessConstPosPerm, nodeAddr, nodeAddr2);

m_ctx->EndEventsBlocking();

std::this_thread::sleep_for(std::chrono::milliseconds(10));
EXPECT_FALSE(isCalled);

nodeAddr2 = m_ctx->CreateNode(ScType::NodeConst);
m_ctx->CreateEdge(ScType::EdgeAccessConstPosPerm, nodeAddr, nodeAddr2);

std::this_thread::sleep_for(std::chrono::milliseconds(10));
EXPECT_TRUE(isCalled);
}

TEST_F(ScEventTest, BlockEventsGuardAndNotEmitAfter)
{
ScAddr const nodeAddr = m_ctx->CreateNode(ScType::NodeConst);

std::atomic_bool isCalled = false;
ScEventAddOutputEdge event(
*m_ctx,
nodeAddr,
[&isCalled](ScAddr const & addr, ScAddr const &, ScAddr const & target)
{
return isCalled = true;
});

ScMemoryContextEventsBlockingGuard guard(*m_ctx);

ScAddr const nodeAddr2 = m_ctx->CreateNode(ScType::NodeConst);
m_ctx->CreateEdge(ScType::EdgeAccessConstPosPerm, nodeAddr, nodeAddr2);

std::this_thread::sleep_for(std::chrono::milliseconds(10));
EXPECT_FALSE(isCalled);
}

TEST_F(ScEventTest, BlockEventsGuardAndEmitAfter)
{
ScAddr const nodeAddr = m_ctx->CreateNode(ScType::NodeConst);

std::atomic_bool isCalled = false;
ScEventAddOutputEdge event(
*m_ctx,
nodeAddr,
[&isCalled](ScAddr const & addr, ScAddr const &, ScAddr const & target)
{
return isCalled = true;
});
{
ScMemoryContextEventsBlockingGuard guard(*m_ctx);

ScAddr const nodeAddr2 = m_ctx->CreateNode(ScType::NodeConst);
m_ctx->CreateEdge(ScType::EdgeAccessConstPosPerm, nodeAddr, nodeAddr2);

std::this_thread::sleep_for(std::chrono::milliseconds(10));
EXPECT_FALSE(isCalled);
}

ScAddr const nodeAddr2 = m_ctx->CreateNode(ScType::NodeConst);
m_ctx->CreateEdge(ScType::EdgeAccessConstPosPerm, nodeAddr, nodeAddr2);

std::this_thread::sleep_for(std::chrono::milliseconds(10));
EXPECT_TRUE(isCalled);
}

0 comments on commit 304405e

Please sign in to comment.