static struct writer_context_s * create_writer (HANDLE fd) { struct writer_context_s *c; SECURITY_ATTRIBUTES sec_attr; DWORD tid; DEBUG1 ("creating new write thread for file handle %p", fd ); memset (&sec_attr, 0, sizeof sec_attr ); sec_attr.nLength = sizeof sec_attr; sec_attr.bInheritHandle = FALSE; c = calloc (1, sizeof *c ); if (!c) return NULL; c->file_hd = fd; c->have_data = CreateEvent (&sec_attr, TRUE, FALSE, NULL); c->is_empty = CreateEvent (&sec_attr, TRUE, TRUE, NULL); c->stopped = CreateEvent (&sec_attr, TRUE, FALSE, NULL); if (!c->have_data || !c->is_empty || !c->stopped ) { DEBUG1 ("** CreateEvent failed: ec=%d\n", (int)GetLastError ()); if (c->have_data) CloseHandle (c->have_data); if (c->is_empty) CloseHandle (c->is_empty); if (c->stopped) CloseHandle (c->stopped); free (c); return NULL; } c->is_empty = set_synchronize (c->is_empty); INIT_LOCK (c->mutex); c->thread_hd = CreateThread (&sec_attr, 0, writer, c, 0, &tid ); if (!c->thread_hd) { DEBUG1 ("** failed to create writer thread: ec=%d\n", (int)GetLastError ()); DESTROY_LOCK (c->mutex); if (c->have_data) CloseHandle (c->have_data); if (c->is_empty) CloseHandle (c->is_empty); if (c->stopped) CloseHandle (c->stopped); free (c); return NULL; } else { /* We set the priority of the thread higher because we know that it only runs for a short time. This greatly helps to increase the performance of the I/O. */ SetThreadPriority (c->thread_hd, get_desired_thread_priority ()); } return c; }
static struct writer_context_s * create_writer (HANDLE fd) { struct writer_context_s *ctx; SECURITY_ATTRIBUTES sec_attr; DWORD tid; TRACE_BEG (DEBUG_SYSIO, "gpgme:create_writer", fd); memset (&sec_attr, 0, sizeof sec_attr); sec_attr.nLength = sizeof sec_attr; sec_attr.bInheritHandle = FALSE; ctx = calloc (1, sizeof *ctx); if (!ctx) { TRACE_SYSERR (errno); return NULL; } ctx->file_hd = fd; ctx->refcount = 1; ctx->have_data = CreateEvent (&sec_attr, TRUE, FALSE, NULL); if (ctx->have_data) ctx->is_empty = CreateEvent (&sec_attr, TRUE, TRUE, NULL); if (ctx->is_empty) ctx->stopped = CreateEvent (&sec_attr, TRUE, FALSE, NULL); if (!ctx->have_data || !ctx->is_empty || !ctx->stopped) { TRACE_LOG1 ("CreateEvent failed: ec=%d", (int) GetLastError ()); if (ctx->have_data) CloseHandle (ctx->have_data); if (ctx->is_empty) CloseHandle (ctx->is_empty); if (ctx->stopped) CloseHandle (ctx->stopped); free (ctx); /* FIXME: Translate the error code. */ TRACE_SYSERR (EIO); return NULL; } ctx->is_empty = set_synchronize (ctx->is_empty); INIT_LOCK (ctx->mutex); ctx->thread_hd = CreateThread (&sec_attr, 0, writer, ctx, 0, &tid ); if (!ctx->thread_hd) { TRACE_LOG1 ("CreateThread failed: ec=%d", (int) GetLastError ()); DESTROY_LOCK (ctx->mutex); if (ctx->have_data) CloseHandle (ctx->have_data); if (ctx->is_empty) CloseHandle (ctx->is_empty); if (ctx->stopped) CloseHandle (ctx->stopped); free (ctx); TRACE_SYSERR (EIO); return NULL; } else { /* We set the priority of the thread higher because we know that it only runs for a short time. This greatly helps to increase the performance of the I/O. */ SetThreadPriority (ctx->thread_hd, get_desired_thread_priority ()); } TRACE_SUC (); return ctx; }