Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ check_PROGRAMS = \
test_ppd_emit \
test_ppd_filter \
test_ppd_generator \
test_ppd_load_profile
test_ppd_load_profile \
test_ppd_thread
TESTS = \
testppd \
test_ppd_localize \
Expand All @@ -81,7 +82,8 @@ TESTS = \
test_ppd_emit \
test_ppd_filter \
test_ppd_generator \
test_ppd_load_profile
test_ppd_load_profile \
test_ppd_thread

libppd_la_SOURCES = \
ppd/ppd-attr.c \
Expand Down Expand Up @@ -267,6 +269,15 @@ test_ppd_load_profile_CFLAGS = \
$(CUPS_CFLAGS) \
$(LIBCUPSFILTERS_CFLAGS)

test_ppd_thread_SOURCES = ppd/test_ppd_thread.c
test_ppd_thread_LDADD = \
libppd.la \
$(CUPS_LIBS)
test_ppd_thread_CFLAGS = \
-I$(srcdir)/ppd/ \
-pthread \
$(CUPS_CFLAGS)

EXTRA_DIST += \
$(pkgppdinclude_DATA) \
$(pkgppddefs_DATA) \
Expand Down
5 changes: 5 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,11 @@ AC_CHECK_HEADERS([dirent.h])
AC_CHECK_HEADER(string.h,AC_DEFINE(HAVE_STRING_H))
AC_CHECK_HEADER(strings.h,AC_DEFINE(HAVE_STRINGS_H))

# ===================================================================
# Check for POSIX threads (mutexes and per-thread data of the library)
# ===================================================================
AC_CHECK_HEADERS([pthread.h], [AC_SEARCH_LIBS([pthread_key_create], [pthread])])

# ===================================
# Check for large files and long long
# ===================================
Expand Down
36 changes: 23 additions & 13 deletions ppd/ppd-cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
//

#include <ppd/string-private.h>
#include <ppd/thread-private.h>
#include <ppd/array-private.h>
#include <ppd/ipp-private.h>
#include <ppd/ppd.h>
Expand Down Expand Up @@ -76,6 +77,8 @@ static int ppd_pwg_compare_finishings(ppd_pwg_finishings_t *a,
static void ppd_pwg_free_finishings(ppd_pwg_finishings_t *f);

char *ppd_cache_status_message = NULL; // Last PPD cache error
static _ppd_mutex_t ppd_cache_status_mutex = _PPD_MUTEX_INITIALIZER;
// Mutex to control access to it


//
Expand All @@ -86,19 +89,16 @@ static void
set_error(const char *message, // I - status-message value
int localize) // I - Localize the message?
{
char *new_message = NULL, // New status-message
*old_message; // Previous status-message


if (!message && errno)
{
message = strerror(errno);
localize = 0;
}

if (ppd_cache_status_message)
{
_ppdStrFree(ppd_cache_status_message);

ppd_cache_status_message = NULL;
}

if (message)
{
if (localize)
Expand All @@ -107,16 +107,26 @@ set_error(const char *message, // I - status-message value
// Get the message catalog...
//

ppd_cache_status_message =
_ppdStrAlloc(cupsLangGetString(cupsLangDefault(),
message));
new_message = _ppdStrAlloc(cupsLangGetString(cupsLangDefault(),
message));
}
else
ppd_cache_status_message = _ppdStrAlloc(message);
new_message = _ppdStrAlloc(message);
}

DEBUG_printf(("4set_error: last_status_message=\"%s\"",
ppd_cache_status_message));
DEBUG_printf(("4set_error: last_status_message=\"%s\"", new_message));

//
// Swap in the new message and free the previous one, so that threads
// setting errors at the same time never free the same string twice...
//

_ppdMutexLock(&ppd_cache_status_mutex);
old_message = ppd_cache_status_message;
ppd_cache_status_message = new_message;
_ppdMutexUnlock(&ppd_cache_status_mutex);

_ppdStrFree(old_message);
}

//
Expand Down
117 changes: 108 additions & 9 deletions ppd/raster-error.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
//

#include "raster-private.h"
#include "thread-private.h"
#include "debug-internal.h"

typedef struct _ppd_raster_error_s // **** Error buffer structure ****
Expand All @@ -22,7 +23,32 @@ typedef struct _ppd_raster_error_s // **** Error buffer structure ****
*end; // End of buffer
} _ppd_raster_error_t;

static _ppd_raster_error_t *buf = NULL;

//
// Local globals...
//

#ifdef HAVE_PTHREAD_H
static _ppd_threadkey_t ppd_raster_error_key = _PPD_THREADKEY_INITIALIZER;
// Thread local storage key
static pthread_once_t ppd_raster_error_key_once = PTHREAD_ONCE_INIT;
// One-time initialization object
#else
static _ppd_raster_error_t ppd_raster_error_buf = { NULL, NULL, NULL };
// Error buffer
#endif // HAVE_PTHREAD_H


//
// Local functions...
//

static _ppd_raster_error_t *ppd_raster_error_buffer(void);
#ifdef HAVE_PTHREAD_H
static void ppd_raster_error_free(void *data);
static void ppd_raster_error_init(void);
#endif // HAVE_PTHREAD_H


//
// '_ppdRasterAddError()' - Add an error message to the error buffer.
Expand All @@ -32,13 +58,18 @@ void
_ppdRasterAddError(const char *f, // I - Printf-style error message
...) // I - Additional arguments as needed
{
_ppd_raster_error_t *buf = ppd_raster_error_buffer();
// Error buffer for this thread
va_list ap; // Pointer to additional arguments
char s[2048]; // Message string
ssize_t bytes; // Bytes in message string


DEBUG_printf(("_ppdRasterAddError(f=\"%s\", ...)", f));

if (!buf)
return;

va_start(ap, f);
bytes = vsnprintf(s, sizeof(s), f, ap);
va_end(ap);
Expand Down Expand Up @@ -98,13 +129,12 @@ _ppdRasterAddError(const char *f, // I - Printf-style error message
void
_ppdRasterClearError(void)
{
if (buf == NULL)
{
buf = malloc(sizeof(_ppd_raster_error_t));
buf->start = NULL;
buf->end = NULL;
buf->current = NULL;
}
_ppd_raster_error_t *buf = ppd_raster_error_buffer();
// Error buffer for this thread


if (!buf)
return;

buf->current = buf->start;

Expand All @@ -124,8 +154,77 @@ _ppdRasterClearError(void)
const char * // O - Last error
_ppdRasterErrorString(void)
{
if (buf->current == buf->start)
_ppd_raster_error_t *buf = ppd_raster_error_buffer();
// Error buffer for this thread


if (!buf || buf->current == buf->start)
return (NULL);
else
return (buf->start);
}


//
// 'ppd_raster_error_buffer()' - Return the error buffer of the current thread.
//

static _ppd_raster_error_t * // O - Error buffer or NULL
ppd_raster_error_buffer(void)
{
#ifdef HAVE_PTHREAD_H
_ppd_raster_error_t *buf; // Error buffer


//
// Initialize the thread key exactly once...
//

pthread_once(&ppd_raster_error_key_once, ppd_raster_error_init);

//
// Allocate the buffer of this thread on first use...
//

if ((buf = (_ppd_raster_error_t *)
_ppdThreadGetData(ppd_raster_error_key)) == NULL)
{
if ((buf = calloc(1, sizeof(_ppd_raster_error_t))) != NULL)
_ppdThreadSetData(ppd_raster_error_key, buf);
}

return (buf);

#else
return (&ppd_raster_error_buf);
#endif // HAVE_PTHREAD_H
}


#ifdef HAVE_PTHREAD_H
//
// 'ppd_raster_error_free()' - Free the error buffer of a thread that exits.
//

static void
ppd_raster_error_free(void *data) // I - Error buffer
{
_ppd_raster_error_t *buf = (_ppd_raster_error_t *)data;
// Error buffer


free(buf->start);
free(buf);
}


//
// 'ppd_raster_error_init()' - Create the thread key for the error buffers.
//

static void
ppd_raster_error_init(void)
{
pthread_key_create(&ppd_raster_error_key, ppd_raster_error_free);
}
#endif // HAVE_PTHREAD_H
Loading
Loading