1/*
2    simple_lock_test.c
3
4    Initializes two contexts in two different threads and tries to get read locks on both at the same time.
5    Hangs at line 24.
6*/
7#include <stdio.h>
8#include <stdarg.h>
9
10#include "test_ccapi_log.h"
11
12#if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__))
13#include <TargetConditionals.h>
14#endif
15
16#ifdef TARGET_OS_MAC
17#include <stdlib.h>
18#include <pthread.h>
19#include <Kerberos/CredentialsCache.h>
20#else
21#include "CredentialsCache.h"
22#endif
23
24
25void *other_thread (void) {
26    cc_int32 err;
27    cc_context_t context = NULL;
28
29    err = cc_initialize(&context, ccapi_version_7, NULL, NULL);
30
31    log_error("thread: attempting lock. may hang. err == %d", err);
32
33    if (!err) {
34        // hangs with cc_lock_read which should succeed immediately, but does not hang with write, upgrade, and downgrade, which fail immediately
35        err = cc_context_lock(context, cc_lock_read, cc_lock_noblock);
36    }
37
38    if (context) {
39        cc_context_unlock(context);
40        cc_context_release(context);
41        context = NULL;
42    }
43    log_error("thread: return. err == %d", err);
44}
45
46
47int main (int argc, char *argv[]) {
48    cc_int32        err;
49    int             status;
50    cc_context_t    context = NULL;
51
52#ifdef TARGET_OS_MAC
53    pthread_t       thread_id;
54#endif
55
56    err = cc_initialize(&context, ccapi_version_7, NULL, NULL);
57    if (!err) {
58        err = cc_context_lock(context, cc_lock_read, cc_lock_noblock);
59    }
60
61    log_error("main: initialized and read locked context. err == %d", err);
62
63#ifdef TARGET_OS_MAC
64   status = pthread_create (&thread_id, NULL, (void *) other_thread, NULL);
65    if (status != 0) {
66        log_error("pthread_create() returned %d", status);
67        exit(-1);
68    }
69
70    pthread_join(thread_id, NULL);
71#else
72
73#endif
74
75    log_error("main: unlocking and releasing context. err == %d", err);
76
77    if (context) {
78        log_error("main: calling cc_context_unlock");
79        cc_context_unlock(context);
80        log_error("main: calling cc_context_release");
81        cc_context_release(context);
82        context = NULL;
83    }
84
85    log_error("main: return. err == %d", err);
86
87#if defined(_WIN32)
88    UNREFERENCED_PARAMETER(status);       // no whining!
89#endif
90    return 0;
91}
92