2 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 #include "gnashconfig.h"
23 #include "SharedMem.h"
30 #if !defined(__riscos__) && !defined(__OS2__)
31 # include <sys/types.h>
39 #if (defined(USE_SYSV_SHM) && defined(HAVE_SHMGET))
40 # define ENABLE_SHARED_MEM 1
42 # undef ENABLE_SHARED_MEM
46 gnash::RcInitFile
& rcfile
= gnash::RcInitFile::getDefaultInstance();
51 SharedMem::SharedMem(size_t size
)
61 SharedMem::~SharedMem()
63 // Nothing to do if we were never attached.
66 if (::shmdt(_addr
) < 0) {
67 const int err
= errno
;
68 log_error("Error detaching shared memory: %s", std::strerror(err
));
71 // We can still try to shut it down.
73 if (::shmctl(_shmid
, IPC_STAT
, &ds
) < 0) {
74 const int err
= errno
;
75 log_error("Error during stat of shared memory segment: %s",
81 // Note that this isn't completely reliable.
83 log_debug("No shared memory users left. Removing segment.");
84 ::shmctl(_shmid
, IPC_RMID
, 0);
91 SharedMem::lock() const
93 struct sembuf sb
= { 0, -1, SEM_UNDO
};
94 const int ret
= ::semop(_semid
, &sb
, 1);
99 SharedMem::unlock() const
101 struct sembuf sb
= { 0, 1, SEM_UNDO
};
102 const int ret
= ::semop(_semid
, &sb
, 1);
109 #if !ENABLE_SHARED_MEM
110 # error "You need SYSV Shared memory support to use this option"
113 // Don't try to attach twice.
114 if (_addr
) return true;
116 _shmkey
= rcfile
.getLCShmKey();
118 // Check rcfile for key; if there isn't one, use the Adobe key.
120 log_debug("No shared memory key specified in rcfile. Using default "
121 "for communication with other players");
122 _shmkey
= 0xdd3adabd;
125 log_debug("Using shared memory key %s",
126 boost::io::group(std::hex
, std::showbase
, _shmkey
));
128 // First get semaphore.
130 // Check if it exists already.
131 _semid
= ::semget(_shmkey
, 1, 0600);
138 unsigned short* array
;
144 // If it does not exist, create it and set its value to 1.
147 _semid
= ::semget(_shmkey
, 1, IPC_CREAT
| 0600);
150 log_error("Failed to get semaphore for shared memory!");
155 const int ret
= ::semctl(_semid
, 0, SETVAL
, s
);
157 log_error("Failed to set semaphore value");
162 // The 4th argument is neither necessary nor used, but we pass it
164 const int semval
= ::semctl(_semid
, 0, GETVAL
, s
);
167 log_error("Need semaphore value of 1 for locking. Cannot "
168 "attach shared memory!");
174 // Then attach shared memory. See if it exists.
175 _shmid
= ::shmget(_shmkey
, _size
, 0600);
179 _shmid
= ::shmget(_shmkey
, _size
, IPC_CREAT
| 0660);
183 log_error("Unable to get shared memory segment!");
187 _addr
= static_cast<iterator
>(::shmat(_shmid
, 0, 0));
190 log_error("Unable to attach shared memory: %s",
191 std::strerror(errno
));
199 } // end of gnash namespace
203 // indent-tabs-mode: t