Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(24)

Side by Side Diff: third_party/android_crazy_linker/src/tests/test_load_library_callbacks.cpp

Issue 1180693002: Update from https://crrev.com/333737 (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: rebased Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // A crazy linker test to test callbacks for delayed execution.
6
7 #include <pthread.h>
8 #include <stdio.h>
9 #include <crazy_linker.h>
10
11 #include "test_util.h"
12
13 namespace {
14
15 typedef void (*FunctionPtr)();
16
17 // Data block passed between callback poster and callback handler.
18 class CallbackData {
19 public:
20 CallbackData() {
21 callback_.handler = NULL;
22 callback_.opaque = NULL;
23 pthread_mutex_init(&mutex_, NULL);
24 pthread_cond_init(&cond_, NULL);
25 }
26
27 crazy_callback_t callback_;
28 pthread_mutex_t mutex_;
29 pthread_cond_t cond_;
30 };
31
32 bool PostCallback(crazy_callback_t* callback, void* poster_opaque) {
33 printf("Post callback, poster_opaque %p, handler %p, opaque %p\n",
34 poster_opaque,
35 callback->handler,
36 callback->opaque);
37
38 CallbackData* callback_data = reinterpret_cast<CallbackData*>(poster_opaque);
39
40 // Set callback_ and signal the arrival of the PostCallback() call.
41 pthread_mutex_lock(&callback_data->mutex_);
42 callback_data->callback_ = *callback;
43 pthread_cond_signal(&callback_data->cond_);
44 pthread_mutex_unlock(&callback_data->mutex_);
45
46 return true;
47 }
48
49 void CheckAndRunCallback(CallbackData* callback_data) {
50 printf("Run callback, callback_data %p\n", callback_data);
51
52 if (!callback_data->callback_.handler) {
53 Panic("Post for delayed execution not invoked\n");
54 }
55
56 // Run the callback, then clear it.
57 crazy_callback_run(&callback_data->callback_);
58 callback_data->callback_.handler = NULL;
59 callback_data->callback_.opaque = NULL;
60 }
61
62 struct ThreadData {
63 crazy_library_t* library;
64 crazy_context_t* context;
65 };
66
67 void* ThreadBody(void *thread_arg) {
68 const ThreadData* thread_data = reinterpret_cast<ThreadData*>(thread_arg);
69
70 // Close the library, asynchronously.
71 crazy_library_close_with_context(thread_data->library, thread_data->context);
72 pthread_exit(NULL);
73 }
74
75 pthread_t AsyncCrazyLibraryCloseWithContext(crazy_library_t* library,
76 crazy_context_t* context,
77 CallbackData* callback_data) {
78 printf("Async close, library %p, context %p\n", library, context);
79
80 ThreadData thread_data = {library, context};
81 void* thread_arg = reinterpret_cast<void*>(&thread_data);
82
83 // Clear the indication that the new thread has called PostCallback().
84 pthread_mutex_lock(&callback_data->mutex_);
85 callback_data->callback_.handler = NULL;
86 callback_data->callback_.opaque = NULL;
87 pthread_mutex_unlock(&callback_data->mutex_);
88
89 // Start the thread that closes the library.
90 pthread_t thread;
91 if (pthread_create(&thread, NULL, ThreadBody, thread_arg) != 0) {
92 Panic("Failed to create thread for close\n");
93 }
94
95 // Wait for the library close to call PostCallback() before returning.
96 printf("Waiting for PostCallback() call\n");
97 pthread_mutex_lock(&callback_data->mutex_);
98 while (!callback_data->callback_.handler) {
99 pthread_cond_wait(&callback_data->cond_, &callback_data->mutex_);
100 }
101 pthread_mutex_unlock(&callback_data->mutex_);
102 printf("Done waiting for PostCallback() call\n");
103
104 return thread;
105 }
106
107 } // namespace
108
109 int main() {
110 crazy_context_t* context = crazy_context_create();
111 crazy_library_t* library;
112
113 // DEBUG
114 crazy_context_set_load_address(context, 0x20000000);
115
116 // Set a callback poster.
117 CallbackData callback_data;
118 crazy_context_set_callback_poster(context, &PostCallback, &callback_data);
119
120 crazy_callback_poster_t poster;
121 void* poster_opaque;
122
123 // Check that the API returns the values we set.
124 crazy_context_get_callback_poster(context, &poster, &poster_opaque);
125 if (poster != &PostCallback || poster_opaque != &callback_data) {
126 Panic("Get callback poster error\n");
127 }
128
129 // Load libfoo.so.
130 if (!crazy_library_open(&library, "libfoo.so", context)) {
131 Panic("Could not open library: %s\n", crazy_context_get_error(context));
132 }
133 CheckAndRunCallback(&callback_data);
134
135 // Find the "Foo" symbol.
136 FunctionPtr foo_func;
137 if (!crazy_library_find_symbol(
138 library, "Foo", reinterpret_cast<void**>(&foo_func))) {
139 Panic("Could not find 'Foo' in libfoo.so\n");
140 }
141
142 // Call it.
143 (*foo_func)();
144
145 // Close the library. Because the close operation will wait for the
146 // callback before returning, we have to run it in a separate thread, and
147 // wait for it to call PostCallback() before continuing.
148 pthread_t thread =
149 AsyncCrazyLibraryCloseWithContext(library, context, &callback_data);
150 CheckAndRunCallback(&callback_data);
151
152 if (pthread_join(thread, NULL) != 0) {
153 Panic("Failed to join thread for close\n");
154 }
155
156 crazy_context_destroy(context);
157 return 0;
158 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698