void CStubBodyGen::GenInterfaceContextDeclaration(std::ofstream& stream,
const Interface& inf) {
- stream << SmartIndent(ReplaceAll(
- CB_INTERFACE_CONTEXT_DECL, "##", GetInterfaceIdWithNamespace(inf)));
+ stream << SmartIndent(GenTemplateString(
+ ReplaceAll(CB_INTERFACE_CONTEXT_DECL, "##",
+ GetInterfaceIdWithNamespace(inf)),
+ [&]()->std::string {
+ if (options_->IsThreadEnabled())
+ return std::string(CB_INTERFACE_CONTEXT_DECL_THREAD_ELEM);
+ return "";
+ }));
+
if (options_->IsThreadEnabled()) {
stream << SmartIndent(ReplaceAll(
CB_INTERFACE_THREAD_FEATURE, "##", GetInterfaceIdWithNamespace(inf)));
void CStubBodyGen::GenInterfaceContextConstructor(std::ofstream& stream,
const Interface& inf) {
- stream << SmartIndent(ReplaceAll(
- CB_INTERFACE_CONTEXT_CTOR, "##", GetInterfaceIdWithNamespace(inf)));
+ stream << SmartIndent(GenTemplateString(
+ ReplaceAll(CB_INTERFACE_CONTEXT_CTOR, "##",
+ GetInterfaceIdWithNamespace(inf)),
+ [&]()->std::string {
+ if (options_->IsThreadEnabled())
+ return std::string(CB_INTERFACE_CONTEXT_CTOR_THREAD_IMPL);
+ return "";
+ }));
}
void CStubBodyGen::GenInterfaceContextDestructor(std::ofstream& stream,
const Interface& inf) {
- stream << SmartIndent(ReplaceAll(
- CB_INTERFACE_CONTEXT_DTOR, "##", GetInterfaceIdWithNamespace(inf)));
+ stream << SmartIndent(GenTemplateString(
+ ReplaceAll(CB_INTERFACE_CONTEXT_DTOR, "##",
+ GetInterfaceIdWithNamespace(inf)),
+ [&]()->std::string {
+ if (options_->IsThreadEnabled())
+ return std::string(CB_INTERFACE_CONTEXT_DTOR_THREAD_VARS);
+ return "";
+ },
+ [&]()->std::string {
+ if (options_->IsThreadEnabled())
+ return std::string(CB_INTERFACE_CONTEXT_DTOR_THREAD_IMPL);
+ return "";
+ }));
}
void CStubBodyGen::GenInterfaceContextFinder(std::ofstream& stream,
__destroy_job(job);
}
g_queue_free(__job_queue);
+__job_queue = NULL;
)__c_cb";
const char CB_INTERFACE_REGISTER[] =
rpc_port_h port;
void *tag;
rpc_port_stub_##_callback_s callback;
- pthread_mutex_t mutex;
- pthread_cond_t cond;
- pthread_t thread;
- bool run_wait_queue;
void *user_data;
+$$
};
)__c_cb";
+const char CB_INTERFACE_CONTEXT_DECL_THREAD_ELEM[] =
+R"__c_cb(pthread_mutex_t mutex;
+pthread_cond_t cond;
+pthread_t thread;
+bool run_wait_queue;
+)__c_cb";
+
const char CB_INTERFACE_THREAD_FEATURE[] =
R"__c_cb(
-static GQueue *__job_queue;
typedef struct {
rpc_port_parcel_h parcel;
rpc_port_h port;
} job_s;
typedef job_s *job_h;
-static int __run_pending_job();
+static GQueue *__job_queue;
+
+static int __run_pending_job(void);
+
static void *__wait_queue(void *data)
{
- rpc_port_stub_##_context_h context =
- (rpc_port_stub_##_context_h)data;
+ rpc_port_stub_##_context_h context = (rpc_port_stub_##_context_h)data;
+
while(context->run_wait_queue) {
pthread_mutex_lock(&context->mutex);
- pthread_cond_wait(&context->cond, &context->mutex);
+ pthread_cond_wait(&context->cond, &context->mutex);
__run_pending_job();
- pthread_mutex_unlock(&context->mutex);
+ pthread_mutex_unlock(&context->mutex);
}
+
return NULL;
}
-static job_h __create_job(rpc_port_parcel_h parcel, rpc_port_h port,
- void *context)
+static job_h __create_job(rpc_port_parcel_h parcel, rpc_port_h port, void *context)
{
- job_h job = (job_s *)calloc(1, sizeof(job_s));
+ job_h job;
+
+ job = (job_s *)calloc(1, sizeof(job_s));
+ if (!job) {
+ _E("Out of memory");
+ return NULL;
+ }
job->parcel = parcel;
job->port = port;
job->context = context;
+
return job;
}
free(job);
}
-static int __add_thread_queue(rpc_port_h port,
- rpc_port_stub_ThreadSample_context_h context)
+static int __add_thread_queue(rpc_port_h port, rpc_port_stub_##_context_h context)
{
+ rpc_port_parcel_h parcel;
job_h job;
int r;
- rpc_port_parcel_h parcel;
r = rpc_port_parcel_create_from_port(&parcel, port);
if (r != 0) {
_E("Failed to create parcel from port");
return r;
}
+
job = __create_job(parcel, port, context);
g_queue_push_tail(__job_queue, job);
if (g_queue_is_empty(__job_queue)) {
- _E("Empty queue ??");
+ _E("Empty queue ##");
return -1;
}
pthread_mutex_lock(&context->mutex);
pthread_cond_signal(&context->cond);
pthread_mutex_unlock(&context->mutex);
+
return 0;
}
)__c_cb";
handle->callback = __##_callback;
handle->user_data = __##_user_data;
- pthread_mutex_init(&handle->mutex, NULL);
- pthread_cond_init(&handle->cond, NULL);
- handle->run_wait_queue = true;
- if (pthread_create(&handle->thread, NULL,
- &__wait_queue, (void *)handle) <0) {
- _E("Fail to create thread");
- return NULL;
- }
-
+$$
return handle;
}
)__c_cb";
+const char CB_INTERFACE_CONTEXT_CTOR_THREAD_IMPL[] =
+R"__c_cb(
+pthread_mutex_init(&handle->mutex, NULL);
+pthread_cond_init(&handle->cond, NULL);
+handle->run_wait_queue = true;
+if (pthread_create(&handle->thread, NULL, &__wait_queue, (void *)handle) < 0) {
+ _E("Fail to create thread");
+ free(handle->instance);
+ free(handle->sender);
+ free(handle);
+ return NULL;
+}
+)__c_cb";
+
const char CB_INTERFACE_CONTEXT_DTOR[] =
R"__c_cb(
static void __destroy_##_context(gpointer data)
{
struct ##_context_s *handle = data;
- void *return_val;
- int err;
-
+$$
if (!handle) {
_E("Critical error!");
return;
free(handle->instance);
free(handle->sender);
+$$
+ free(handle);
+}
+)__c_cb";
- handle->run_wait_queue = false;
- pthread_mutex_lock(&handle->mutex);
- pthread_cond_signal(&handle->cond);
- pthread_mutex_unlock(&handle->mutex);
- err = pthread_join(handle->thread, &return_val);
- if (0 != err)
- _E("joining thread error [%d].", err);
+const char CB_INTERFACE_CONTEXT_DTOR_THREAD_VARS[] =
+R"__c_cb(void *retval = NULL;
+int ret;
+)__c_cb";
- pthread_cond_destroy(&handle->cond);
- pthread_mutex_destroy(&handle->mutex);
+const char CB_INTERFACE_CONTEXT_DTOR_THREAD_IMPL[] =
+R"__c_cb(
+handle->run_wait_queue = false;
+pthread_mutex_lock(&handle->mutex);
+pthread_cond_signal(&handle->cond);
+pthread_mutex_unlock(&handle->mutex);
- free(handle);
-}
+ret = pthread_join(handle->thread, &retval);
+if (ret != 0)
+ _E("joining thread error [%d].", ret);
+
+pthread_cond_destroy(&handle->cond);
+pthread_mutex_destroy(&handle->mutex);
)__c_cb";
const char CB_INTERFACE_CONTEXT_FINDER[] =