diff --git a/ChangeLog b/ChangeLog index aea2877762..3cda278a57 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2003-12-27 Manish Singh + + * app/main.c + * app/plug-in/plug-in-shm.c + * libgimp/gimp.c: POSIX shared memory tile transport implementation, + and a little code cleanup of the SysV and Win32 implementations. + + * configure.in: checks for shm_open, default to POSIX shared memory + transport on OS X. + 2003-12-27 Pedro Gimeno * plug-ins/common/jigsaw.c (jigsaw): actually don't crash when diff --git a/app/main.c b/app/main.c index 643f95067f..aad8c3262e 100644 --- a/app/main.c +++ b/app/main.c @@ -223,7 +223,7 @@ main (int argc, g_set_application_name (_("The GIMP")); -#if defined (HAVE_SHM_H) || defined (G_OS_WIN32) +#if defined (USE_SYSV_SHM) || defined (USE_POSIX_SHM) || defined (G_OS_WIN32) use_shm = TRUE; #endif diff --git a/app/plug-in/gimppluginshm.c b/app/plug-in/gimppluginshm.c index 43392dfb15..27f9fe7a94 100644 --- a/app/plug-in/gimppluginshm.c +++ b/app/plug-in/gimppluginshm.c @@ -20,6 +20,10 @@ #include +#include + +#if defined(USE_SYSV_SHM) + #ifdef HAVE_IPC_H #include #endif @@ -28,6 +32,17 @@ #include #endif +#elif defined(USE_POSIX_SHM) + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include +#include + +#endif /* USE_POSIX_SHM */ + #include #if defined(G_OS_WIN32) || defined(G_WITH_CYGWIN) @@ -41,6 +56,8 @@ #include #endif +#define USE_WIN32_SHM 1 + #endif /* G_OS_WIN32 || G_WITH_CYGWIN */ #include "plug-in-types.h" @@ -57,12 +74,16 @@ struct _PlugInShm gint shm_ID; guchar *shm_addr; -#if defined(G_OS_WIN32) || defined(G_WITH_CYGWIN) +#if defined(USE_WIN32_SHM) HANDLE shm_handle; #endif }; +#define TILE_MAP_SIZE (TILE_WIDTH * TILE_HEIGHT * 4) + +#define ERRMSG_SHM_DISABLE "Disabling shared memory tile transport" + void plug_in_shm_init (Gimp *gimp) { @@ -71,47 +92,47 @@ plug_in_shm_init (Gimp *gimp) * we'll fall back on sending the data over the pipe. */ -#ifdef HAVE_SHM_H +#if defined(USE_SYSV_SHM) + /* Use SysV shared memory mechanisms for transferring tile data. */ + g_return_if_fail (GIMP_IS_GIMP (gimp)); gimp->plug_in_shm = g_new0 (PlugInShm, 1); gimp->plug_in_shm->shm_ID = -1; - gimp->plug_in_shm->shm_ID = shmget (IPC_PRIVATE, - TILE_WIDTH * TILE_HEIGHT * 4, + gimp->plug_in_shm->shm_ID = shmget (IPC_PRIVATE, TILE_MAP_SIZE, IPC_CREAT | 0600); - if (gimp->plug_in_shm->shm_ID == -1) - { - g_message ("shmget() failed: Disabling shared memory tile transport."); - } - else + if (gimp->plug_in_shm->shm_ID != -1) { gimp->plug_in_shm->shm_addr = (guchar *) shmat (gimp->plug_in_shm->shm_ID, NULL, 0); if (gimp->plug_in_shm->shm_addr == (guchar *) -1) - { - g_message ("shmat() failed: Disabling shared memory tile transport."); - shmctl (gimp->plug_in_shm->shm_ID, IPC_RMID, NULL); - gimp->plug_in_shm->shm_ID = -1; - } + { + g_warning ("shmat() failed: %s\n" ERRMSG_SHM_DISABLE, + g_strerror (errno)); + shmctl (gimp->plug_in_shm->shm_ID, IPC_RMID, NULL); + gimp->plug_in_shm->shm_ID = -1; + } #ifdef IPC_RMID_DEFERRED_RELEASE if (gimp->plug_in_shm->shm_addr != (guchar *) -1) - shmctl (gimp->plug_in_shm->shm_ID, IPC_RMID, NULL); + shmctl (gimp->plug_in_shm->shm_ID, IPC_RMID, NULL); #endif } + else + { + g_warning ("shmget() failed: %s\n" ERRMSG_SHM_DISABLE, + g_strerror (errno)); + } -#else /* ! HAVE_SHM_H */ +#elif defined(USE_WIN32_SHM) + + /* Use Win32 shared memory mechanisms for transferring tile data. */ -#if defined(G_OS_WIN32) || defined(G_WITH_CYGWIN) - /* Use Win32 shared memory mechanisms for - * transfering tile data. - */ gint pid; gchar fileMapName[MAX_PATH]; - gint tileByteSize = TILE_WIDTH * TILE_HEIGHT * 4; g_return_if_fail (GIMP_IS_GIMP (gimp)); @@ -127,7 +148,8 @@ plug_in_shm_init (Gimp *gimp) /* Create the file mapping into paging space */ gimp->plug_in_shm->shm_handle = CreateFileMapping ((HANDLE) 0xFFFFFFFF, NULL, PAGE_READWRITE, 0, - tileByteSize, fileMapName); + TILE_MAP_SIZE, + fileMapName); if (gimp->plug_in_shm->shm_handle) { @@ -135,25 +157,78 @@ plug_in_shm_init (Gimp *gimp) gimp->plug_in_shm->shm_addr = (guchar *) MapViewOfFile (gimp->plug_in_shm->shm_handle, FILE_MAP_ALL_ACCESS, - 0, 0, tileByteSize); + 0, 0, TILE_MAP_SIZE); /* Verify that we mapped our view */ if (gimp->plug_in_shm->shm_addr) - gimp->plug_in_shm->shm_ID = pid; + gimp->plug_in_shm->shm_ID = pid; else - g_warning ("MapViewOfFile error: " - "%d... disabling shared memory transport", - GetLastError()); + g_warning ("MapViewOfFile error: %d... " ERRMSG_SHM_DISABLE, + GetLastError ()); } else { - g_warning ("CreateFileMapping error: " - "%d... disabling shared memory transport", - GetLastError()); + g_warning ("CreateFileMapping error: %d... " ERRMSG_SHM_DISABLE, + GetLastError ()); } -#endif /* G_OS_WIN32 || G_WITH_CYGWIN */ -#endif /* HAVE_SHM_H */ +#elif defined(USE_POSIX_SHM) + + /* Use POSIX shared memory mechanisms for transferring tile data. */ + + gint pid; + gchar shm_handle[32]; + gint shm_fd; + + g_return_if_fail (GIMP_IS_GIMP (gimp)); + + gimp->plug_in_shm = g_new0 (PlugInShm, 1); + gimp->plug_in_shm->shm_ID = -1; + + /* Our shared memory id will be our process ID */ + pid = getpid (); + + /* From the id, derive the file map name */ + g_snprintf (shm_handle, sizeof (shm_handle), "/gimp-shm-%d", pid); + + /* Create the file mapping into paging space */ + shm_fd = shm_open (shm_handle, O_RDWR | O_CREAT, 0600); + + if (shm_fd != -1) + { + if (ftruncate (shm_fd, TILE_MAP_SIZE) != -1) + { + /* Map the shared memory into our address space for use */ + gimp->plug_in_shm->shm_addr = (guchar *) + mmap (NULL, TILE_MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, + shm_fd, 0); + + /* Verify that we mapped our view */ + if (gimp->plug_in_shm->shm_addr != MAP_FAILED) + gimp->plug_in_shm->shm_ID = pid; + else + { + g_warning ("mmap() failed: %s\n" ERRMSG_SHM_DISABLE, + g_strerror (errno)); + + shm_unlink (shm_handle); + } + } + else + { + g_warning ("ftruncate() failed: %s\n" ERRMSG_SHM_DISABLE, + g_strerror (errno)); + + shm_unlink (shm_handle); + } + } + else + { + g_warning ("shm_open() failed: %s\n" ERRMSG_SHM_DISABLE, + g_strerror (errno)); + } + +#endif } void @@ -162,14 +237,9 @@ plug_in_shm_exit (Gimp *gimp) g_return_if_fail (GIMP_IS_GIMP (gimp)); g_return_if_fail (gimp->plug_in_shm != NULL); -#if defined(G_OS_WIN32) || defined(G_WITH_CYGWIN) +#if defined (USE_SYSV_SHM) - CloseHandle (gimp->plug_in_shm->shm_handle); - -#else /* ! (G_OS_WIN32 || G_WITH_CYGWIN) */ - -#ifdef HAVE_SHM_H -#ifndef IPC_RMID_DEFERRED_RELEASE +#ifndef IPC_RMID_DEFERRED_RELEASE if (gimp->plug_in_shm->shm_ID != -1) { shmdt (gimp->plug_in_shm->shm_addr); @@ -181,9 +251,29 @@ plug_in_shm_exit (Gimp *gimp) shmdt (gimp->plug_in_shm->shm_addr); } #endif -#endif /* HAVE_SHM_H */ -#endif /* G_OS_WIN32 || G_WITH_CYGWIN */ +#elif defined(USE_WIN32_SHM) + + if (gimp->plug_in_shm->shm_handle) + { + CloseHandle (gimp->plug_in_shm->shm_handle); + } + +#elif defined(USE_POSIX_SHM) + + if (gimp->plug_in_shm->shm_ID != -1) + { + gchar shm_handle[32]; + + munmap (gimp->plug_in_shm->shm_addr, TILE_MAP_SIZE); + + g_snprintf (shm_handle, sizeof (shm_handle), "/gimp-shm-%d", + gimp->plug_in_shm->shm_ID); + + shm_unlink (shm_handle); + } + +#endif g_free (gimp->plug_in_shm); gimp->plug_in_shm = NULL; diff --git a/app/plug-in/plug-in-shm.c b/app/plug-in/plug-in-shm.c index 43392dfb15..27f9fe7a94 100644 --- a/app/plug-in/plug-in-shm.c +++ b/app/plug-in/plug-in-shm.c @@ -20,6 +20,10 @@ #include +#include + +#if defined(USE_SYSV_SHM) + #ifdef HAVE_IPC_H #include #endif @@ -28,6 +32,17 @@ #include #endif +#elif defined(USE_POSIX_SHM) + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include +#include + +#endif /* USE_POSIX_SHM */ + #include #if defined(G_OS_WIN32) || defined(G_WITH_CYGWIN) @@ -41,6 +56,8 @@ #include #endif +#define USE_WIN32_SHM 1 + #endif /* G_OS_WIN32 || G_WITH_CYGWIN */ #include "plug-in-types.h" @@ -57,12 +74,16 @@ struct _PlugInShm gint shm_ID; guchar *shm_addr; -#if defined(G_OS_WIN32) || defined(G_WITH_CYGWIN) +#if defined(USE_WIN32_SHM) HANDLE shm_handle; #endif }; +#define TILE_MAP_SIZE (TILE_WIDTH * TILE_HEIGHT * 4) + +#define ERRMSG_SHM_DISABLE "Disabling shared memory tile transport" + void plug_in_shm_init (Gimp *gimp) { @@ -71,47 +92,47 @@ plug_in_shm_init (Gimp *gimp) * we'll fall back on sending the data over the pipe. */ -#ifdef HAVE_SHM_H +#if defined(USE_SYSV_SHM) + /* Use SysV shared memory mechanisms for transferring tile data. */ + g_return_if_fail (GIMP_IS_GIMP (gimp)); gimp->plug_in_shm = g_new0 (PlugInShm, 1); gimp->plug_in_shm->shm_ID = -1; - gimp->plug_in_shm->shm_ID = shmget (IPC_PRIVATE, - TILE_WIDTH * TILE_HEIGHT * 4, + gimp->plug_in_shm->shm_ID = shmget (IPC_PRIVATE, TILE_MAP_SIZE, IPC_CREAT | 0600); - if (gimp->plug_in_shm->shm_ID == -1) - { - g_message ("shmget() failed: Disabling shared memory tile transport."); - } - else + if (gimp->plug_in_shm->shm_ID != -1) { gimp->plug_in_shm->shm_addr = (guchar *) shmat (gimp->plug_in_shm->shm_ID, NULL, 0); if (gimp->plug_in_shm->shm_addr == (guchar *) -1) - { - g_message ("shmat() failed: Disabling shared memory tile transport."); - shmctl (gimp->plug_in_shm->shm_ID, IPC_RMID, NULL); - gimp->plug_in_shm->shm_ID = -1; - } + { + g_warning ("shmat() failed: %s\n" ERRMSG_SHM_DISABLE, + g_strerror (errno)); + shmctl (gimp->plug_in_shm->shm_ID, IPC_RMID, NULL); + gimp->plug_in_shm->shm_ID = -1; + } #ifdef IPC_RMID_DEFERRED_RELEASE if (gimp->plug_in_shm->shm_addr != (guchar *) -1) - shmctl (gimp->plug_in_shm->shm_ID, IPC_RMID, NULL); + shmctl (gimp->plug_in_shm->shm_ID, IPC_RMID, NULL); #endif } + else + { + g_warning ("shmget() failed: %s\n" ERRMSG_SHM_DISABLE, + g_strerror (errno)); + } -#else /* ! HAVE_SHM_H */ +#elif defined(USE_WIN32_SHM) + + /* Use Win32 shared memory mechanisms for transferring tile data. */ -#if defined(G_OS_WIN32) || defined(G_WITH_CYGWIN) - /* Use Win32 shared memory mechanisms for - * transfering tile data. - */ gint pid; gchar fileMapName[MAX_PATH]; - gint tileByteSize = TILE_WIDTH * TILE_HEIGHT * 4; g_return_if_fail (GIMP_IS_GIMP (gimp)); @@ -127,7 +148,8 @@ plug_in_shm_init (Gimp *gimp) /* Create the file mapping into paging space */ gimp->plug_in_shm->shm_handle = CreateFileMapping ((HANDLE) 0xFFFFFFFF, NULL, PAGE_READWRITE, 0, - tileByteSize, fileMapName); + TILE_MAP_SIZE, + fileMapName); if (gimp->plug_in_shm->shm_handle) { @@ -135,25 +157,78 @@ plug_in_shm_init (Gimp *gimp) gimp->plug_in_shm->shm_addr = (guchar *) MapViewOfFile (gimp->plug_in_shm->shm_handle, FILE_MAP_ALL_ACCESS, - 0, 0, tileByteSize); + 0, 0, TILE_MAP_SIZE); /* Verify that we mapped our view */ if (gimp->plug_in_shm->shm_addr) - gimp->plug_in_shm->shm_ID = pid; + gimp->plug_in_shm->shm_ID = pid; else - g_warning ("MapViewOfFile error: " - "%d... disabling shared memory transport", - GetLastError()); + g_warning ("MapViewOfFile error: %d... " ERRMSG_SHM_DISABLE, + GetLastError ()); } else { - g_warning ("CreateFileMapping error: " - "%d... disabling shared memory transport", - GetLastError()); + g_warning ("CreateFileMapping error: %d... " ERRMSG_SHM_DISABLE, + GetLastError ()); } -#endif /* G_OS_WIN32 || G_WITH_CYGWIN */ -#endif /* HAVE_SHM_H */ +#elif defined(USE_POSIX_SHM) + + /* Use POSIX shared memory mechanisms for transferring tile data. */ + + gint pid; + gchar shm_handle[32]; + gint shm_fd; + + g_return_if_fail (GIMP_IS_GIMP (gimp)); + + gimp->plug_in_shm = g_new0 (PlugInShm, 1); + gimp->plug_in_shm->shm_ID = -1; + + /* Our shared memory id will be our process ID */ + pid = getpid (); + + /* From the id, derive the file map name */ + g_snprintf (shm_handle, sizeof (shm_handle), "/gimp-shm-%d", pid); + + /* Create the file mapping into paging space */ + shm_fd = shm_open (shm_handle, O_RDWR | O_CREAT, 0600); + + if (shm_fd != -1) + { + if (ftruncate (shm_fd, TILE_MAP_SIZE) != -1) + { + /* Map the shared memory into our address space for use */ + gimp->plug_in_shm->shm_addr = (guchar *) + mmap (NULL, TILE_MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, + shm_fd, 0); + + /* Verify that we mapped our view */ + if (gimp->plug_in_shm->shm_addr != MAP_FAILED) + gimp->plug_in_shm->shm_ID = pid; + else + { + g_warning ("mmap() failed: %s\n" ERRMSG_SHM_DISABLE, + g_strerror (errno)); + + shm_unlink (shm_handle); + } + } + else + { + g_warning ("ftruncate() failed: %s\n" ERRMSG_SHM_DISABLE, + g_strerror (errno)); + + shm_unlink (shm_handle); + } + } + else + { + g_warning ("shm_open() failed: %s\n" ERRMSG_SHM_DISABLE, + g_strerror (errno)); + } + +#endif } void @@ -162,14 +237,9 @@ plug_in_shm_exit (Gimp *gimp) g_return_if_fail (GIMP_IS_GIMP (gimp)); g_return_if_fail (gimp->plug_in_shm != NULL); -#if defined(G_OS_WIN32) || defined(G_WITH_CYGWIN) +#if defined (USE_SYSV_SHM) - CloseHandle (gimp->plug_in_shm->shm_handle); - -#else /* ! (G_OS_WIN32 || G_WITH_CYGWIN) */ - -#ifdef HAVE_SHM_H -#ifndef IPC_RMID_DEFERRED_RELEASE +#ifndef IPC_RMID_DEFERRED_RELEASE if (gimp->plug_in_shm->shm_ID != -1) { shmdt (gimp->plug_in_shm->shm_addr); @@ -181,9 +251,29 @@ plug_in_shm_exit (Gimp *gimp) shmdt (gimp->plug_in_shm->shm_addr); } #endif -#endif /* HAVE_SHM_H */ -#endif /* G_OS_WIN32 || G_WITH_CYGWIN */ +#elif defined(USE_WIN32_SHM) + + if (gimp->plug_in_shm->shm_handle) + { + CloseHandle (gimp->plug_in_shm->shm_handle); + } + +#elif defined(USE_POSIX_SHM) + + if (gimp->plug_in_shm->shm_ID != -1) + { + gchar shm_handle[32]; + + munmap (gimp->plug_in_shm->shm_addr, TILE_MAP_SIZE); + + g_snprintf (shm_handle, sizeof (shm_handle), "/gimp-shm-%d", + gimp->plug_in_shm->shm_ID); + + shm_unlink (shm_handle); + } + +#endif g_free (gimp->plug_in_shm); gimp->plug_in_shm = NULL; diff --git a/configure.in b/configure.in index 50897b6bf5..7627390bb8 100644 --- a/configure.in +++ b/configure.in @@ -518,8 +518,7 @@ fi dnl MacOS X has broken SysV shm case "$host_os" in darwin* | rhapsody* | machten*) - # We can put something else here when something that works is implemented - shmdefault=none + shmdefault=posix ;; *) shmdefault=sysv @@ -527,15 +526,18 @@ case "$host_os" in esac shmtype=auto -AC_ARG_WITH(shm, [ --with-shm=none|sysv|auto shared memory transport type (default=auto)], shmtype=$with_shm) +AC_ARG_WITH(shm, [ --with-shm=none|sysv|posix|auto shared memory transport type (default=auto)], shmtype=$with_shm) case $shmtype in - none|sysv) ;; + none|sysv|posix) ;; auto) shmtype=$shmdefault ;; - *) AC_MSG_ERROR([Invalid shared memory transport type: use none, sysv, or auto.]);; + *) AC_MSG_ERROR([Invalid shared memory transport type: use none, sysv, posix, or auto.]);; esac -if test "x$shmtype" = "xsysv"; then + +if test "x$platform_win32" = "xyes"; then + shmtype=win32 +elif test "x$shmtype" = "xsysv"; then AC_CHECK_HEADER(sys/ipc.h, [AC_DEFINE(HAVE_IPC_H, 1, [Define to 1 if you have the heacder file.])], @@ -544,6 +546,7 @@ if test "x$shmtype" = "xsysv"; then [AC_DEFINE(HAVE_SHM_H, 1, [Define to 1 if you have the header file.])], no_sys_shm=yes) + if test "$ac_cv_header_sys_shm_h" = "yes"; then AC_MSG_CHECKING(whether shmctl IPC_RMID allowes subsequent attaches) AC_TRY_RUN([ @@ -574,9 +577,30 @@ if test "x$shmtype" = "xsysv"; then AC_MSG_RESULT(yes), AC_MSG_RESULT(no), AC_MSG_RESULT(assuming no)) + + AC_DEFINE(USE_SYSV_SHM, 1, [Define to 1 to use SYSV shared memory]) + else + shmtype=none + fi +elif test "x$shmtype" = "xposix"; then + AC_CHECK_LIB(rt, shm_open) + + AC_CHECK_HEADER(sys/mman.h, + [AC_DEFINE(HAVE_MMAN_H, 1, + [Define to 1 if you have the heacder file.])], + no_sys_mman=yes) + + if test "$ac_cv_func_mmap" = "yes" && + test "$ac_cv_lib_rt_shm_open" = "yes" && + test "$ac_cv_header_sys_mman_h" = "yes"; then + AC_DEFINE(USE_POSIX_SHM, 1, [Define to 1 to use POSIX shared memory]) + else + shmtype=none fi fi +AC_MSG_CHECKING(for shared memory transport type) +AC_MSG_RESULT($shmtype) ######################## # Define a symbol prefix diff --git a/libgimp/gimp.c b/libgimp/gimp.c index 7848a9f8c5..2917bc305d 100644 --- a/libgimp/gimp.c +++ b/libgimp/gimp.c @@ -56,6 +56,12 @@ #include #endif +#ifdef HAVE_SYS_SELECT_H +#include +#endif + +#if defined(USE_SYSV_SHM) + #ifdef HAVE_IPC_H #include #endif @@ -64,14 +70,22 @@ #include #endif -#ifdef HAVE_SYS_SELECT_H -#include +#elif defined(USE_POSIX_SHM) + +#ifdef HAVE_UNISTD_H +#include #endif +#include +#include + +#endif /* USE_POSIX_SHM */ + #if defined(G_OS_WIN32) || defined(G_WITH_CYGWIN) # define STRICT # include # undef RGB +# define USE_WIN32_SHM 1 #endif #ifdef __EMX__ @@ -96,6 +110,10 @@ #include "gimpunitcache.h" +#define TILE_MAP_SIZE (_tile_width * _tile_height * 4) + +#define ERRMSG_SHM_FAILED "Could not attach to gimp shared memory segment" + /* Maybe this should go in a public header if we add other things to it */ typedef enum { @@ -151,7 +169,7 @@ const guint gimp_major_version = GIMP_MAJOR_VERSION; const guint gimp_minor_version = GIMP_MINOR_VERSION; const guint gimp_micro_version = GIMP_MICRO_VERSION; -#if defined(G_OS_WIN32) || defined(G_WITH_CYGWIN) +#ifdef USE_WIN32_SHM static HANDLE shm_handle; #endif @@ -1342,13 +1360,21 @@ gimp_close (void) if (PLUG_IN_INFO.quit_proc) (* PLUG_IN_INFO.quit_proc) (); -#if defined(G_OS_WIN32) || defined(G_WITH_CYGWIN) - CloseHandle (shm_handle); -#else -#ifdef HAVE_SHM_H +#if defined(USE_SYSV_SHM) + if ((_shm_ID != -1) && _shm_addr) shmdt ((char*) _shm_addr); -#endif + +#elif defined(USE_WIN32_SHM) + + if (shm_handle) + CloseHandle (shm_handle); + +#elif defined(USE_POSIX_SHM) + + if ((_shm_ID != -1) && (_shm_addr != MAP_FAILED)) + munmap (_shm_addr, TILE_MAP_SIZE); + #endif gp_quit_write (_writechannel, NULL); @@ -1606,13 +1632,23 @@ gimp_config (GPConfig *config) if (_shm_ID != -1) { -#if defined(G_OS_WIN32) || defined(G_WITH_CYGWIN) - /* - * Use Win32 shared memory mechanisms for - * transfering tile data - */ +#if defined(USE_SYSV_SHM) + + /* Use SysV shared memory mechanisms for transferring tile data. */ + + _shm_addr = (guchar *) shmat (_shm_ID, 0, 0); + + if (_shm_addr == (guchar *) -1) + { + g_error ("shmat() failed: %s\n" ERRMSG_SHM_FAILED, + g_strerror (errno)); + } + +#elif defined(USE_WIN32_SHM) + + /* Use Win32 shared memory mechanisms for transferring tile data. */ + gchar fileMapName[128]; - gint tileByteSize = _tile_width * _tile_height * 4; /* From the id, derive the file map name */ g_snprintf (fileMapName, sizeof (fileMapName), "GIMP%d.SHM", _shm_ID); @@ -1625,27 +1661,54 @@ gimp_config (GPConfig *config) /* Map the shared memory into our address space for use */ _shm_addr = (guchar *) MapViewOfFile (shm_handle, FILE_MAP_ALL_ACCESS, - 0, 0, tileByteSize); + 0, 0, TILE_MAP_SIZE); /* Verify that we mapped our view */ if (!_shm_addr) { - g_warning ("MapViewOfFile error: %d... disabling shared memory transport", - GetLastError()); + g_error ("MapViewOfFile error: %d... " ERRMSG_SHM_FAILED, + GetLastError ()); } } else { - g_warning ("OpenFileMapping error: %d... disabling shared memory transport", - GetLastError()); + g_error ("OpenFileMapping error: %d... " ERRMSG_SHM_FAILED, + GetLastError ()); } -#else -#ifdef HAVE_SHM_H - _shm_addr = (guchar*) shmat (_shm_ID, 0, 0); - if (_shm_addr == (guchar*) -1) - g_error ("could not attach to gimp shared memory segment"); -#endif +#elif defined(USE_POSIX_SHM) + + /* Use POSIX shared memory mechanisms for transferring tile data. */ + + gchar map_file[32]; + gint shm_fd; + + /* From the id, derive the file map name */ + g_snprintf (map_file, sizeof (map_file), "/gimp-shm-%d", _shm_ID); + + /* Open the file mapping */ + shm_fd = shm_open (map_file, O_RDWR, 0600); + + if (shm_fd != -1) + { + /* Map the shared memory into our address space for use */ + _shm_addr = (guchar *) mmap (NULL, TILE_MAP_SIZE, + PROT_READ | PROT_WRITE, MAP_SHARED, + shm_fd, 0); + + /* Verify that we mapped our view */ + if (_shm_addr == MAP_FAILED) + { + g_error ("mmap() failed: %s\n" ERRMSG_SHM_FAILED, + g_strerror (errno)); + } + } + else + { + g_error ("shm_open() failed: %s\n" ERRMSG_SHM_FAILED, + g_strerror (errno)); + } + #endif } }