Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Shared Pointer interface #130

Open
P-p-H-d opened this issue Oct 12, 2024 · 1 comment
Open

New Shared Pointer interface #130

P-p-H-d opened this issue Oct 12, 2024 · 1 comment
Assignees

Comments

@P-p-H-d
Copy link
Owner

P-p-H-d commented Oct 12, 2024

Here is the proposal for the new shared pointer interface. It will put m-shared, m-i-shared and m-concurrent as obsolete headers.
It provides:

  • optional full encapsulation of the data between header and C file by default,
  • user select level of concurrency protection for the data (like m-concurrent)
  • shared pointer semantic as pure pointer (like m-i-shared)

Note: Header definition doesn't need to provide a working oplist: only the types are needed and the existence of methods are only tested here.

// 3 Cases:
// * atomic_int + lock		:	SHARED_STRONG_PTR
// * atomic_int + no lock	:	SHARED_PTR
// * int + no lock		:	SHARED_WEAK_PTR

// For each case, 3 macros:

// Only declare functions (For header file)
SHARED_PTR_DECL(shared, shared_t, oplist)

// Declare & definition as static inline
SHARED_PTR_DEF(name, type, oplist)

// Definition only (For C file)
SHARED_PTR_DEF_EXTERN(name, type, oplist)

// Header define only:
typedef struct shared_s shared_t;

// C define as:
struct shared_s {
  atomic_int cpt;  // Or int
  mlock      lock; // Optional
  cond       cond; // Optional
  type       data;
};

// 
shared_t *shared_new(void);   				// If INIT
shared_t *shared_new_copy(const shared_t *); 		// If INIT_SET
void	  shared_copy(shared_t *, const shared_t *); 	// If SET
shared_t *shared_acquire_owner(shared_t *);
void      shared_release_owner(shared_t *);
void      shared_clear(shared *);                       // Same as shared_release_owner
shared_t *shared_make[_...](... [EMPLACE_TYPE] ... );	// If EMPLACE_TYPE

void      shared_swap(shared_t *, shared_t *);          // If SWAP
void      shared_reset(shared_t*);                      // If RESET
bool      shared_empty_p(const shared_t*);		// If EMPTY_P
size_t    shared_size(const shared_t*); 		// If GET_SIZE
bool      shared_equal_p(const shared_t*, const shared_t*); // If EQUAL
size_t    shared_hash(const shared_t*); 		// If HASH
int       shared_cmp(const shared_t*,const shared_t*); 	// If CMP

void      shared_add(shared_t *, const shared_t *);      // If ADD
void      shared_sub(shared_t *, const shared_t *);      // If SUB
void      shared_mul(shared_t *, const shared_t *);      // If MUL
void      shared_div(shared_t *, const shared_t *);      // If DIV

// Map interface if KEY_TYPE / VALUE_TYPE & GET_KEY / SAFE_GET_KEY / SET_KEY / ERASE_KEY
bool M_F(name, _get_key)(value_type *value, shared_t *, const key_type key);
void M_F(name, _safe_get_key)(value_type *value, shared_t *, const key_type key);
void M_F(name, _set_key))(shared_t *, const key_type key, const value_type value);
bool M_F(name, _erase_key)(shared_t *, const key_type key);

// Push interface if SUBTYPE & PUSH / PUSH_MOVE / POP / POP_MOVE
void M_F(name, _push)(shared_t *, subtype obj);
void M_F(name, _push_move)(shared_t *, subtype *obj);
bool M_F(name, _try_push)(shared_t *, subtype obj);
bool M_F(name, _try_push_move)(shared_t *, subtype *obj);
void M_F(name, _emplace_ ...)(shared_t *, ...); // If OPLIST.EMPLACE_TYPE
bool M_F(name, _try_emplace_ ...)(shared_t *, ...); // If OPLIST.EMPLACE_TYPE
void M_F(name, _pop)(subtype *obj, shared_t *);
bool M_F(name, _try_pop)(subtype *obj, shared_t *);
void M_F(name, _pop_move)(subtype *obj, shared_t *);
bool M_F(name, _try_pop_move)(subtype *obj, shared_t *);

// Iterators if IT_TYPE
// For each element from FIRST LAST, apply callback and break if callback returns false
// Return true if all elements have been scanned, false otherwise
bool M_F(name, _apply)(shared_t*, bool(*callback)(void *data, subtype*), void *data);
bool M_F(name, _for_each)(shared_t*, bool(*callback)(void *data, const subtype*), void *data);
// If IT_PREVIOUS & IT_LAST
// For each element from LAST to FIRST, apply callback and break if callback returns false
// Return true if all elements have been scanned, false otherwise
bool M_F(name, _apply_reverse)(shared_t*, bool(*callback)(void *data, subtype*), void *data);
bool M_F(name, _for_each_reverse)(shared_t*, bool(*callback)(void *data, const subtype*), void *data);

// IO
void M_F(name, _out_str)(FILE *, shared_t *);
bool M_F(name, _in_str)(shared_t *, FILE *);
void M_F(name, _get_str)(string_t, shared_t *, bool append);
bool M_F(name, _parse_str)(shared_t *, const char cstr[], const char **e);
m_serial_return_code_t M_F(name, _out_serial)(m_serial_write_t f, shared_t *);
m_serial_return_code_t M_F(name, _in_serial)(shared_t *, m_serial_write_t f);

// Not exported:
void M_F(name, _read_lock)(shared_t *);
void M_F(name, _read_wait)(shared_t *);
void M_F(name, _read_unlock)(shared_t *);
void M_F(name, _write_lock)(shared_t *);
void M_F(name, _write_wait)(shared_t *);
void M_F(name, _write_signal)(shared_t *);
void M_F(name, _write_unlock)(shared_t *);

type *M_F(name, _ref)(shared_t *);
const type *M_F(name, _cref)(shared_t *);

// 2 OPLISTS
SHARED_PTR_OPLIST // Oplist where the data is the shared pointer itself (acquire / release)
SHARED_OBJ_OPLIST // Oplist where the data is the shared object (object copy)

Don't hesitate to comment on the interface.

@P-p-H-d P-p-H-d self-assigned this Oct 12, 2024
@P-p-H-d
Copy link
Owner Author

P-p-H-d commented Nov 2, 2024

Header m-shared-ptr is available. Needs to implement proper test and documentation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant