Skip to content

Commit

Permalink
add mutex functions to the API
Browse files Browse the repository at this point in the history
  • Loading branch information
tonycoz committed Nov 24, 2012
1 parent ca1a577 commit 24c9233
Show file tree
Hide file tree
Showing 14 changed files with 352 additions and 10 deletions.
3 changes: 3 additions & 0 deletions MANIFEST
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,9 @@ MANIFEST
MANIFEST.SKIP
map.c
maskimg.c
mutexnull.c
mutexpthr.c
mutexwin.c
palimg.c
paste.im
plug.h
Expand Down
19 changes: 19 additions & 0 deletions Makefile.PL
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,25 @@ my @objs = qw(Imager.o context.o draw.o polygon.o image.o io.o iolayer.o
bmp.o tga.o color.o fills.o imgdouble.o limits.o hlines.o
imext.o scale.o rubthru.o render.o paste.o compose.o flip.o);

if ($Config{useithreads}) {
if ($Config{i_pthread}) {
print "POSIX threads\n";
push @objs, "mutexpthr.o";
}
elsif ($^O eq 'MSWin32') {
print "Win32 threads\n";
push @objs, "mutexwin.o";
}
else {
print "Unsupported threading model\n";
push @objs, "mutexnull.o";
}
}
else {
print "No threads\n";
push @objs, "mutexnull.o";
}

my @typemaps = qw(typemap.local typemap);
if ($] < 5.008) {
unshift @typemaps, "typemap.oldperl";
Expand Down
6 changes: 6 additions & 0 deletions imager.h
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,12 @@ extern im_context_t im_context_clone(im_context_t ctx, const char *where);

extern im_context_t (*im_get_context)(void);

/* mutex API */
extern i_mutex_t i_mutex_new(void);
extern void i_mutex_destroy(i_mutex_t m);
extern void i_mutex_lock(i_mutex_t m);
extern void i_mutex_unlock(i_mutex_t m);

#include "imio.h"

#endif
12 changes: 12 additions & 0 deletions imdatatypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,18 @@ typedef enum {
ic_color
} i_combine_t;

/*
=item i_mutex_t
X<i_mutex>
=category mutex
=synopsis i_mutex_t mutex;
Opaque type for Imager's mutex API.
=cut
*/
typedef struct i_mutex_tag *i_mutex_t;

/*
describes an axis of a MM font.
Modelled on FT2's FT_MM_Axis.
Expand Down
6 changes: 5 additions & 1 deletion imext.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,11 @@ im_ext_funcs imager_function_table =
im_loog,
im_context_refinc,
im_context_refdec,
im_errors
im_errors,
i_mutex_new,
i_mutex_destroy,
i_mutex_lock,
i_mutex_unlock
};

/* in general these functions aren't called by Imager internally, but
Expand Down
5 changes: 5 additions & 0 deletions imext.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,11 @@ extern im_ext_funcs *imager_function_ext_table;
#define io_slurp(ig, datap) ((im_extt->f_io_slurp)((ig), (datap)))
#define io_glue_destroy(ig) ((im_extt->f_io_glue_destroy)(ig))

#define i_mutex_new() ((im_extt->f_i_mutex_new)())
#define i_mutex_destroy(m) ((im_extt->f_i_mutex_destroy)(m))
#define i_mutex_lock(m) ((im_extt->f_i_mutex_lock)(m))
#define i_mutex_unlock(m) ((im_extt->f_i_mutex_unlock)(m))

#define im_push_errorf (im_extt->f_im_push_errorf)

#ifdef IMAGER_LOG
Expand Down
7 changes: 7 additions & 0 deletions imexttypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,13 @@ typedef struct {
void (*f_im_context_refinc)(im_context_t, const char *where);
void (*f_im_context_refdec)(im_context_t, const char *where);
i_errmsg *(*f_im_errors)(im_context_t);
i_mutex_t (*f_i_mutex_new)(void);
void (*f_i_mutex_destroy)(i_mutex_t m);
void (*f_i_mutex_lock)(i_mutex_t m);
void (*f_i_mutex_unlock)(i_mutex_t m);
im_slot_t (*f_im_context_slot_new)(im_slot_destroy_t);
int (*f_im_context_slot_set)(im_context_t, im_slot_t, void *);
void *(*f_im_context_slot_get)(im_context_t, im_slot_t);
} im_ext_funcs;

#define PERL_FUNCTION_TABLE_NAME "Imager::__ext_func_table"
Expand Down
25 changes: 25 additions & 0 deletions lib/Imager/API.pod
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,31 @@ This can be used to define your own local context macro:
...
}

=head1 Mutex Functions

Since some libraries are not thread safe, Imager's API includes some
simple mutex functions.

To create a mutex:

i_mutex_t m = i_mutex_new();

To control or lock the mutex:

i_mutex_lock(m);

To release or unlock the mutex:

i_mutex_unlock(m);

To free any resources used by the mutex:

i_mutex_destroy(m);

I most cases where you'd use these functions, your code would create
the mutex in your BOOT section, then lock and unlock the mutex as
needed to control access to the library.

=head1 AUTHOR

Tony Cook <tonyc@cpan.org>
Expand Down
91 changes: 83 additions & 8 deletions lib/Imager/APIRef.pod
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,12 @@ Imager::APIRef - Imager's C API - reference.

# Logging

# Mutex functions
i_mutex_t m = i_mutex_new();
i_mutex_destroy(m);
i_mutex_lock(m);
i_mutex_unlock(m);

# Paletted images

# Tags
Expand Down Expand Up @@ -1876,6 +1882,58 @@ This is an internal function called by the mm_log() macro.
From: File log.c


=back

=head2 Mutex functions

=over

=item i_mutex_new()

i_mutex_t m = i_mutex_new();

Create a mutex.

If a critical section cannot be created for whatever reason, Imager
will abort.


=for comment
From: File mutexwin.c

=item i_mutex_destroy(m)

i_mutex_destroy(m);

Destroy a mutex.


=for comment
From: File mutexwin.c

=item i_mutex_lock(m)

i_mutex_lock(m);

Lock the mutex, waiting if another thread has the mutex locked.


=for comment
From: File mutexwin.c

=item i_mutex_unlock(m)

i_mutex_unlock(m);

Release the mutex.

The behavior of releasing a mutex you don't hold is unspecified.


=for comment
From: File mutexwin.c


=back

=head2 Paletted images
Expand Down Expand Up @@ -2210,6 +2268,31 @@ Returns ~0UL on failure.
=for comment
From: File io.c

=item im_context_refdec(ctx, where)
X<im_context_refdec API>
=section Context objects

im_context_refdec(aIMCTX, "a description");

Remove a reference to the context, releasing it if all references have
been removed.


=for comment
From: File context.c

=item im_context_refinc(ctx, where)
X<im_context_refinc API>
=section Context objects

im_context_refinc(aIMCTX, "a description");

Add a new reference to the context.


=for comment
From: File context.c

=item im_errors(ctx)

i_errmsg *errors = im_errors(aIMCTX);
Expand Down Expand Up @@ -2251,14 +2334,6 @@ will change:

=item *

B<im_context_refdec>

=item *

B<im_context_refinc>

=item *

B<im_lhead>

=item *
Expand Down
37 changes: 37 additions & 0 deletions mutexnull.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
dummy mutexes, for non-threaded builds
*/

#include "imageri.h"

#include <pthread.h>

/* documented in mutexwin.c */

struct i_mutex_tag {
int dummy;
};

i_mutex_t
i_mutex_new(void) {
i_mutex_t m;

m = mymalloc(sizeof(*m));

return m;
}

void
i_mutex_destroy(i_mutex_t m) {
myfree(m);
}

void
i_mutex_lock(i_mutex_t m) {
(void)m;
}

void
i_mutex_unlock(i_mutex_t m) {
(void)m;
}
42 changes: 42 additions & 0 deletions mutexpthr.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
pthreads mutexes
*/

#include "imageri.h"

#include <pthread.h>
#include <errno.h>

/* documented in mutexwin.c */

struct i_mutex_tag {
pthread_mutex_t mutex;
};

i_mutex_t
i_mutex_new(void) {
i_mutex_t m;

m = mymalloc(sizeof(*m));
if (pthread_mutex_init(&m->mutex, NULL) != 0) {
i_fatal(3, "Error initializing mutex %d", errno);
}

return m;
}

void
i_mutex_destroy(i_mutex_t m) {
pthread_mutex_destroy(&(m->mutex));
myfree(m);
}

void
i_mutex_lock(i_mutex_t m) {
pthread_mutex_lock(&(m->mutex));
}

void
i_mutex_unlock(i_mutex_t m) {
pthread_mutex_unlock(&m->mutex);
}
Loading

0 comments on commit 24c9233

Please sign in to comment.