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

Add a named thread-safe variable abstraction or a lock-free hash table #3

Open
nicowilliams opened this issue May 6, 2023 · 0 comments
Assignees

Comments

@nicowilliams
Copy link
Owner

nicowilliams commented May 6, 2023

Imagine you're building an API that reads in and parses, say, certificates and keys, or a trust anchor store (so, certificates). It might be slow-ish -- perhaps too slow to do too frequently. And maybe you have to do this multiple times for multiple different certificate stores. It'd be nice to use a TSV (thread-safe variable) to hold an immutable loaded-store value, but to have one per-store. Now the certificate stores have names (e.g., path names), so it would be even nicer to not have to keep track of which TSV is for which store, just use the store's name to get to the TSV.

This:

int  thread_safe_var_init_named(thread_safe_var *,
                                thread_safe_var_dtor_f,
                                void *, /*namespace*/
                                const char * /*name*/);

would be very nice. If called multiple times, it should not re-initialized a TSV, just output the existing TSV. Though perhaps an thread_safe_var_find_named(); would also be nice:

int  thread_safe_var_find_named(thread_safe_var * /*TSV out*/,
                                void * /*namespace*/,
                                const char * /*name*/);

The namespace would typically be the address of a static (global) in the caller's object.

The name would be a C string.

As well it would be nice to have:

int  thread_safe_var_get_named(void *, /*namespace*/
                               const char * /*name*/
                               void ** /*value out*/,
                               uint64_t * /*version out*/);

and have that be fast even though a lookup would be needed. The lookup can be made fast by keeping a per-thread sorted array of name&TSV values that can be binary searched.

Then one could write:

        static int namespace;
        cert_store *cs;

        (void) thread_safe_var_get_named(&namespace, "/etc/ssl/certs/foo", &cs, NULL);

or

static int namespace;

// ...
        cert_store *cs;

        if (cts->tsv_cs == NULL &&
            thread_safe_var_init_named(&ctx->tsv_cs, cert_store_dtor, &namespace, cert_store_path))
            err(1, "Could not initialize TSV for cert store %s", cert_store_path);
        
        if (thread_safe_var_get(cts->tsv_cs, &cs, NULL))
            /* This would be ENOMEM in pthread_set_specific() */
            err(1, "Could not read the TSV for cert store %s", cert_store_path);

        if (cs == NULL) {
            if (load_cert_store(cert_store_path, tsv_cs) /* sets the TSV */)
                err(1, "Could not load certificate store %s", cert_store_path);
        } else if (cert_store_last_reload_time(cs) > 300) {
            if (load_cert_store(cert_store_path, tsv_cs) /* sets the TSV */)
                warn("Could not reload certificate store %s", cert_store_path);
            if (thread_safe_var_get(cts->tsv_cs, &cs, NULL))
                err(1, "Could not read the TSV for cert store %s", cert_store_path);
        }

        /* Use the certificate store in `cs` */

Alternatively a lock-free hash table where reading a key's value causes the value returned to be safe to use until the next key/value is read or until the reference is "put":

typedef struct ctp_hash_table_s *ctp_hash_table;
int ctp_hash_table_init(ctp_hash_table *, size_t);
void ctp_hash_table_destroy(ctp_hash_table *);
const void *ctp_hash_table_get(ctp_hash_table, const char *);
void ctp_hash_table_put(ctp_hash_table);
int ctp_hash_table_set(ctp_hash_table, const char *, const void *);
@nicowilliams nicowilliams self-assigned this May 6, 2023
@nicowilliams nicowilliams changed the title Add a named thread-safe variable abstraction Add a named thread-safe variable abstraction or a lock-free hash table May 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant