app/main.c app/plug-in/plug-in-shm.c POSIX shared memory tile transport

2003-12-27  Manish Singh  <yosh@gimp.org>

        * 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.
This commit is contained in:
Manish Singh 2003-12-27 08:07:15 +00:00 committed by Manish Singh
parent 913cdc1aed
commit 6bf0f76be8
6 changed files with 391 additions and 114 deletions

View File

@ -1,3 +1,13 @@
2003-12-27 Manish Singh <yosh@gimp.org>
* 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 <pggimeno@wanadoo.es> 2003-12-27 Pedro Gimeno <pggimeno@wanadoo.es>
* plug-ins/common/jigsaw.c (jigsaw): actually don't crash when * plug-ins/common/jigsaw.c (jigsaw): actually don't crash when

View File

@ -223,7 +223,7 @@ main (int argc,
g_set_application_name (_("The GIMP")); 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; use_shm = TRUE;
#endif #endif

View File

@ -20,6 +20,10 @@
#include <sys/types.h> #include <sys/types.h>
#include <errno.h>
#if defined(USE_SYSV_SHM)
#ifdef HAVE_IPC_H #ifdef HAVE_IPC_H
#include <sys/ipc.h> #include <sys/ipc.h>
#endif #endif
@ -28,6 +32,17 @@
#include <sys/shm.h> #include <sys/shm.h>
#endif #endif
#elif defined(USE_POSIX_SHM)
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <fcntl.h>
#include <sys/mman.h>
#endif /* USE_POSIX_SHM */
#include <glib-object.h> #include <glib-object.h>
#if defined(G_OS_WIN32) || defined(G_WITH_CYGWIN) #if defined(G_OS_WIN32) || defined(G_WITH_CYGWIN)
@ -41,6 +56,8 @@
#include <io.h> #include <io.h>
#endif #endif
#define USE_WIN32_SHM 1
#endif /* G_OS_WIN32 || G_WITH_CYGWIN */ #endif /* G_OS_WIN32 || G_WITH_CYGWIN */
#include "plug-in-types.h" #include "plug-in-types.h"
@ -57,12 +74,16 @@ struct _PlugInShm
gint shm_ID; gint shm_ID;
guchar *shm_addr; guchar *shm_addr;
#if defined(G_OS_WIN32) || defined(G_WITH_CYGWIN) #if defined(USE_WIN32_SHM)
HANDLE shm_handle; HANDLE shm_handle;
#endif #endif
}; };
#define TILE_MAP_SIZE (TILE_WIDTH * TILE_HEIGHT * 4)
#define ERRMSG_SHM_DISABLE "Disabling shared memory tile transport"
void void
plug_in_shm_init (Gimp *gimp) plug_in_shm_init (Gimp *gimp)
{ {
@ -71,28 +92,26 @@ plug_in_shm_init (Gimp *gimp)
* we'll fall back on sending the data over the pipe. * 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)); g_return_if_fail (GIMP_IS_GIMP (gimp));
gimp->plug_in_shm = g_new0 (PlugInShm, 1); gimp->plug_in_shm = g_new0 (PlugInShm, 1);
gimp->plug_in_shm->shm_ID = -1; gimp->plug_in_shm->shm_ID = -1;
gimp->plug_in_shm->shm_ID = shmget (IPC_PRIVATE, gimp->plug_in_shm->shm_ID = shmget (IPC_PRIVATE, TILE_MAP_SIZE,
TILE_WIDTH * TILE_HEIGHT * 4,
IPC_CREAT | 0600); IPC_CREAT | 0600);
if (gimp->plug_in_shm->shm_ID == -1) if (gimp->plug_in_shm->shm_ID != -1)
{
g_message ("shmget() failed: Disabling shared memory tile transport.");
}
else
{ {
gimp->plug_in_shm->shm_addr = (guchar *) gimp->plug_in_shm->shm_addr = (guchar *)
shmat (gimp->plug_in_shm->shm_ID, NULL, 0); shmat (gimp->plug_in_shm->shm_ID, NULL, 0);
if (gimp->plug_in_shm->shm_addr == (guchar *) -1) if (gimp->plug_in_shm->shm_addr == (guchar *) -1)
{ {
g_message ("shmat() failed: Disabling shared memory tile transport."); g_warning ("shmat() failed: %s\n" ERRMSG_SHM_DISABLE,
g_strerror (errno));
shmctl (gimp->plug_in_shm->shm_ID, IPC_RMID, NULL); shmctl (gimp->plug_in_shm->shm_ID, IPC_RMID, NULL);
gimp->plug_in_shm->shm_ID = -1; gimp->plug_in_shm->shm_ID = -1;
} }
@ -102,16 +121,18 @@ plug_in_shm_init (Gimp *gimp)
shmctl (gimp->plug_in_shm->shm_ID, IPC_RMID, NULL); shmctl (gimp->plug_in_shm->shm_ID, IPC_RMID, NULL);
#endif #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; gint pid;
gchar fileMapName[MAX_PATH]; gchar fileMapName[MAX_PATH];
gint tileByteSize = TILE_WIDTH * TILE_HEIGHT * 4;
g_return_if_fail (GIMP_IS_GIMP (gimp)); 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 */ /* Create the file mapping into paging space */
gimp->plug_in_shm->shm_handle = CreateFileMapping ((HANDLE) 0xFFFFFFFF, NULL, gimp->plug_in_shm->shm_handle = CreateFileMapping ((HANDLE) 0xFFFFFFFF, NULL,
PAGE_READWRITE, 0, PAGE_READWRITE, 0,
tileByteSize, fileMapName); TILE_MAP_SIZE,
fileMapName);
if (gimp->plug_in_shm->shm_handle) if (gimp->plug_in_shm->shm_handle)
{ {
@ -135,25 +157,78 @@ plug_in_shm_init (Gimp *gimp)
gimp->plug_in_shm->shm_addr = (guchar *) gimp->plug_in_shm->shm_addr = (guchar *)
MapViewOfFile (gimp->plug_in_shm->shm_handle, MapViewOfFile (gimp->plug_in_shm->shm_handle,
FILE_MAP_ALL_ACCESS, FILE_MAP_ALL_ACCESS,
0, 0, tileByteSize); 0, 0, TILE_MAP_SIZE);
/* Verify that we mapped our view */ /* Verify that we mapped our view */
if (gimp->plug_in_shm->shm_addr) if (gimp->plug_in_shm->shm_addr)
gimp->plug_in_shm->shm_ID = pid; gimp->plug_in_shm->shm_ID = pid;
else else
g_warning ("MapViewOfFile error: " g_warning ("MapViewOfFile error: %d... " ERRMSG_SHM_DISABLE,
"%d... disabling shared memory transport",
GetLastError ()); GetLastError ());
} }
else else
{ {
g_warning ("CreateFileMapping error: " g_warning ("CreateFileMapping error: %d... " ERRMSG_SHM_DISABLE,
"%d... disabling shared memory transport",
GetLastError ()); 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 void
@ -162,13 +237,8 @@ plug_in_shm_exit (Gimp *gimp)
g_return_if_fail (GIMP_IS_GIMP (gimp)); g_return_if_fail (GIMP_IS_GIMP (gimp));
g_return_if_fail (gimp->plug_in_shm != NULL); 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) if (gimp->plug_in_shm->shm_ID != -1)
{ {
@ -181,9 +251,29 @@ plug_in_shm_exit (Gimp *gimp)
shmdt (gimp->plug_in_shm->shm_addr); shmdt (gimp->plug_in_shm->shm_addr);
} }
#endif #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); g_free (gimp->plug_in_shm);
gimp->plug_in_shm = NULL; gimp->plug_in_shm = NULL;

View File

@ -20,6 +20,10 @@
#include <sys/types.h> #include <sys/types.h>
#include <errno.h>
#if defined(USE_SYSV_SHM)
#ifdef HAVE_IPC_H #ifdef HAVE_IPC_H
#include <sys/ipc.h> #include <sys/ipc.h>
#endif #endif
@ -28,6 +32,17 @@
#include <sys/shm.h> #include <sys/shm.h>
#endif #endif
#elif defined(USE_POSIX_SHM)
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <fcntl.h>
#include <sys/mman.h>
#endif /* USE_POSIX_SHM */
#include <glib-object.h> #include <glib-object.h>
#if defined(G_OS_WIN32) || defined(G_WITH_CYGWIN) #if defined(G_OS_WIN32) || defined(G_WITH_CYGWIN)
@ -41,6 +56,8 @@
#include <io.h> #include <io.h>
#endif #endif
#define USE_WIN32_SHM 1
#endif /* G_OS_WIN32 || G_WITH_CYGWIN */ #endif /* G_OS_WIN32 || G_WITH_CYGWIN */
#include "plug-in-types.h" #include "plug-in-types.h"
@ -57,12 +74,16 @@ struct _PlugInShm
gint shm_ID; gint shm_ID;
guchar *shm_addr; guchar *shm_addr;
#if defined(G_OS_WIN32) || defined(G_WITH_CYGWIN) #if defined(USE_WIN32_SHM)
HANDLE shm_handle; HANDLE shm_handle;
#endif #endif
}; };
#define TILE_MAP_SIZE (TILE_WIDTH * TILE_HEIGHT * 4)
#define ERRMSG_SHM_DISABLE "Disabling shared memory tile transport"
void void
plug_in_shm_init (Gimp *gimp) plug_in_shm_init (Gimp *gimp)
{ {
@ -71,28 +92,26 @@ plug_in_shm_init (Gimp *gimp)
* we'll fall back on sending the data over the pipe. * 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)); g_return_if_fail (GIMP_IS_GIMP (gimp));
gimp->plug_in_shm = g_new0 (PlugInShm, 1); gimp->plug_in_shm = g_new0 (PlugInShm, 1);
gimp->plug_in_shm->shm_ID = -1; gimp->plug_in_shm->shm_ID = -1;
gimp->plug_in_shm->shm_ID = shmget (IPC_PRIVATE, gimp->plug_in_shm->shm_ID = shmget (IPC_PRIVATE, TILE_MAP_SIZE,
TILE_WIDTH * TILE_HEIGHT * 4,
IPC_CREAT | 0600); IPC_CREAT | 0600);
if (gimp->plug_in_shm->shm_ID == -1) if (gimp->plug_in_shm->shm_ID != -1)
{
g_message ("shmget() failed: Disabling shared memory tile transport.");
}
else
{ {
gimp->plug_in_shm->shm_addr = (guchar *) gimp->plug_in_shm->shm_addr = (guchar *)
shmat (gimp->plug_in_shm->shm_ID, NULL, 0); shmat (gimp->plug_in_shm->shm_ID, NULL, 0);
if (gimp->plug_in_shm->shm_addr == (guchar *) -1) if (gimp->plug_in_shm->shm_addr == (guchar *) -1)
{ {
g_message ("shmat() failed: Disabling shared memory tile transport."); g_warning ("shmat() failed: %s\n" ERRMSG_SHM_DISABLE,
g_strerror (errno));
shmctl (gimp->plug_in_shm->shm_ID, IPC_RMID, NULL); shmctl (gimp->plug_in_shm->shm_ID, IPC_RMID, NULL);
gimp->plug_in_shm->shm_ID = -1; gimp->plug_in_shm->shm_ID = -1;
} }
@ -102,16 +121,18 @@ plug_in_shm_init (Gimp *gimp)
shmctl (gimp->plug_in_shm->shm_ID, IPC_RMID, NULL); shmctl (gimp->plug_in_shm->shm_ID, IPC_RMID, NULL);
#endif #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; gint pid;
gchar fileMapName[MAX_PATH]; gchar fileMapName[MAX_PATH];
gint tileByteSize = TILE_WIDTH * TILE_HEIGHT * 4;
g_return_if_fail (GIMP_IS_GIMP (gimp)); 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 */ /* Create the file mapping into paging space */
gimp->plug_in_shm->shm_handle = CreateFileMapping ((HANDLE) 0xFFFFFFFF, NULL, gimp->plug_in_shm->shm_handle = CreateFileMapping ((HANDLE) 0xFFFFFFFF, NULL,
PAGE_READWRITE, 0, PAGE_READWRITE, 0,
tileByteSize, fileMapName); TILE_MAP_SIZE,
fileMapName);
if (gimp->plug_in_shm->shm_handle) if (gimp->plug_in_shm->shm_handle)
{ {
@ -135,25 +157,78 @@ plug_in_shm_init (Gimp *gimp)
gimp->plug_in_shm->shm_addr = (guchar *) gimp->plug_in_shm->shm_addr = (guchar *)
MapViewOfFile (gimp->plug_in_shm->shm_handle, MapViewOfFile (gimp->plug_in_shm->shm_handle,
FILE_MAP_ALL_ACCESS, FILE_MAP_ALL_ACCESS,
0, 0, tileByteSize); 0, 0, TILE_MAP_SIZE);
/* Verify that we mapped our view */ /* Verify that we mapped our view */
if (gimp->plug_in_shm->shm_addr) if (gimp->plug_in_shm->shm_addr)
gimp->plug_in_shm->shm_ID = pid; gimp->plug_in_shm->shm_ID = pid;
else else
g_warning ("MapViewOfFile error: " g_warning ("MapViewOfFile error: %d... " ERRMSG_SHM_DISABLE,
"%d... disabling shared memory transport",
GetLastError ()); GetLastError ());
} }
else else
{ {
g_warning ("CreateFileMapping error: " g_warning ("CreateFileMapping error: %d... " ERRMSG_SHM_DISABLE,
"%d... disabling shared memory transport",
GetLastError ()); 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 void
@ -162,13 +237,8 @@ plug_in_shm_exit (Gimp *gimp)
g_return_if_fail (GIMP_IS_GIMP (gimp)); g_return_if_fail (GIMP_IS_GIMP (gimp));
g_return_if_fail (gimp->plug_in_shm != NULL); 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) if (gimp->plug_in_shm->shm_ID != -1)
{ {
@ -181,9 +251,29 @@ plug_in_shm_exit (Gimp *gimp)
shmdt (gimp->plug_in_shm->shm_addr); shmdt (gimp->plug_in_shm->shm_addr);
} }
#endif #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); g_free (gimp->plug_in_shm);
gimp->plug_in_shm = NULL; gimp->plug_in_shm = NULL;

View File

@ -518,8 +518,7 @@ fi
dnl MacOS X has broken SysV shm dnl MacOS X has broken SysV shm
case "$host_os" in case "$host_os" in
darwin* | rhapsody* | machten*) darwin* | rhapsody* | machten*)
# We can put something else here when something that works is implemented shmdefault=posix
shmdefault=none
;; ;;
*) *)
shmdefault=sysv shmdefault=sysv
@ -527,15 +526,18 @@ case "$host_os" in
esac esac
shmtype=auto 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 case $shmtype in
none|sysv) ;; none|sysv|posix) ;;
auto) shmtype=$shmdefault ;; 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 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_CHECK_HEADER(sys/ipc.h,
[AC_DEFINE(HAVE_IPC_H, 1, [AC_DEFINE(HAVE_IPC_H, 1,
[Define to 1 if you have the <sys/ipc.h> heacder file.])], [Define to 1 if you have the <sys/ipc.h> heacder file.])],
@ -544,6 +546,7 @@ if test "x$shmtype" = "xsysv"; then
[AC_DEFINE(HAVE_SHM_H, 1, [AC_DEFINE(HAVE_SHM_H, 1,
[Define to 1 if you have the <sys/shm.h> header file.])], [Define to 1 if you have the <sys/shm.h> header file.])],
no_sys_shm=yes) no_sys_shm=yes)
if test "$ac_cv_header_sys_shm_h" = "yes"; then if test "$ac_cv_header_sys_shm_h" = "yes"; then
AC_MSG_CHECKING(whether shmctl IPC_RMID allowes subsequent attaches) AC_MSG_CHECKING(whether shmctl IPC_RMID allowes subsequent attaches)
AC_TRY_RUN([ AC_TRY_RUN([
@ -574,9 +577,30 @@ if test "x$shmtype" = "xsysv"; then
AC_MSG_RESULT(yes), AC_MSG_RESULT(yes),
AC_MSG_RESULT(no), AC_MSG_RESULT(no),
AC_MSG_RESULT(assuming 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 <sys/mman.h> 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
fi fi
AC_MSG_CHECKING(for shared memory transport type)
AC_MSG_RESULT($shmtype)
######################## ########################
# Define a symbol prefix # Define a symbol prefix

View File

@ -56,6 +56,12 @@
#include <signal.h> #include <signal.h>
#endif #endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#if defined(USE_SYSV_SHM)
#ifdef HAVE_IPC_H #ifdef HAVE_IPC_H
#include <sys/ipc.h> #include <sys/ipc.h>
#endif #endif
@ -64,14 +70,22 @@
#include <sys/shm.h> #include <sys/shm.h>
#endif #endif
#ifdef HAVE_SYS_SELECT_H #elif defined(USE_POSIX_SHM)
#include <sys/select.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif #endif
#include <fcntl.h>
#include <sys/mman.h>
#endif /* USE_POSIX_SHM */
#if defined(G_OS_WIN32) || defined(G_WITH_CYGWIN) #if defined(G_OS_WIN32) || defined(G_WITH_CYGWIN)
# define STRICT # define STRICT
# include <windows.h> # include <windows.h>
# undef RGB # undef RGB
# define USE_WIN32_SHM 1
#endif #endif
#ifdef __EMX__ #ifdef __EMX__
@ -96,6 +110,10 @@
#include "gimpunitcache.h" #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 */ /* Maybe this should go in a public header if we add other things to it */
typedef enum 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_minor_version = GIMP_MINOR_VERSION;
const guint gimp_micro_version = GIMP_MICRO_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; static HANDLE shm_handle;
#endif #endif
@ -1342,13 +1360,21 @@ gimp_close (void)
if (PLUG_IN_INFO.quit_proc) if (PLUG_IN_INFO.quit_proc)
(* PLUG_IN_INFO.quit_proc) (); (* PLUG_IN_INFO.quit_proc) ();
#if defined(G_OS_WIN32) || defined(G_WITH_CYGWIN) #if defined(USE_SYSV_SHM)
CloseHandle (shm_handle);
#else
#ifdef HAVE_SHM_H
if ((_shm_ID != -1) && _shm_addr) if ((_shm_ID != -1) && _shm_addr)
shmdt ((char*) _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 #endif
gp_quit_write (_writechannel, NULL); gp_quit_write (_writechannel, NULL);
@ -1606,13 +1632,23 @@ gimp_config (GPConfig *config)
if (_shm_ID != -1) if (_shm_ID != -1)
{ {
#if defined(G_OS_WIN32) || defined(G_WITH_CYGWIN) #if defined(USE_SYSV_SHM)
/*
* Use Win32 shared memory mechanisms for /* Use SysV shared memory mechanisms for transferring tile data. */
* transfering 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]; gchar fileMapName[128];
gint tileByteSize = _tile_width * _tile_height * 4;
/* From the id, derive the file map name */ /* From the id, derive the file map name */
g_snprintf (fileMapName, sizeof (fileMapName), "GIMP%d.SHM", _shm_ID); 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 */ /* Map the shared memory into our address space for use */
_shm_addr = (guchar *) MapViewOfFile (shm_handle, _shm_addr = (guchar *) MapViewOfFile (shm_handle,
FILE_MAP_ALL_ACCESS, FILE_MAP_ALL_ACCESS,
0, 0, tileByteSize); 0, 0, TILE_MAP_SIZE);
/* Verify that we mapped our view */ /* Verify that we mapped our view */
if (!_shm_addr) if (!_shm_addr)
{ {
g_warning ("MapViewOfFile error: %d... disabling shared memory transport", g_error ("MapViewOfFile error: %d... " ERRMSG_SHM_FAILED,
GetLastError ()); GetLastError ());
} }
} }
else else
{ {
g_warning ("OpenFileMapping error: %d... disabling shared memory transport", g_error ("OpenFileMapping error: %d... " ERRMSG_SHM_FAILED,
GetLastError ()); GetLastError ());
} }
#else
#ifdef HAVE_SHM_H
_shm_addr = (guchar*) shmat (_shm_ID, 0, 0);
if (_shm_addr == (guchar*) -1) #elif defined(USE_POSIX_SHM)
g_error ("could not attach to gimp shared memory segment");
#endif /* 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 #endif
} }
} }