summaryrefslogtreecommitdiffhomepage
path: root/examples/sptr_pthread.c
blob: d71ce97d4e379cf7d4b115224fcd6b50a163c4f5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
// example based on https://en.cppreference.com/w/cpp/memory/shared_ptr
#if defined __GNUC__ || defined __linux__

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <time.h>

struct Base
{
    int value;
} typedef Base;

#define i_val Base
#define i_drop(x) printf("Base::~Base()\n")
#define i_tag base
#define i_opt c_no_cmp
#include <stc/csptr.h>

void* thr(csptr_base* lp)
{
    sleep(1);
    static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
    c_autoscope (pthread_mutex_lock(&mtx), pthread_mutex_unlock(&mtx))
    {
        printf("local pointer in a thread:\n"
                "  p.get() = %p, p.use_count() = %ld\n", (void*)lp->get, *lp->use_count);
    }
    /* atomically decrease ref. */
    csptr_base_drop(lp);
    return NULL;
}

int main()
{
    csptr_base p = csptr_base_from((Base){42});

    printf("Created a Base\n"
           "  p.get() = %p, p.use_count() = %ld\n", (void*)p.get, *p.use_count);
    enum {N = 3};
    pthread_t t[N];
    csptr_base c[N];
    c_forrange (i, N) {
        c[i] = csptr_base_clone(p);
        pthread_create(&t[i], NULL, (void*(*)(void*))thr, &c[i]);
    }

    printf("Shared ownership between %d threads and released\n"
           "ownership from main:\n"
           "  p.get() = %p, p.use_count() = %ld\n", N, (void*)p.get, *p.use_count);
    csptr_base_reset(&p);

    c_forrange (i, N) pthread_join(t[i], NULL);
    printf("All threads completed, the last one deleted Base\n");
}

#else
int main() {}
#endif