[Gambas-bugtracker] Bug #2540: Gambas does not seem to be writing to same shared memory as local processes
bugtracker at gambaswiki.org
bugtracker at gambaswiki.org
Wed May 4 03:14:09 CEST 2022
http://gambaswiki.org/bugtracker/edit?object=BUG.2540&from=L21haW4-
Gary SPRANG reported a new bug.
Summary
-------
Gambas does not seem to be writing to same shared memory as local processes
Type : Bug
Priority : Medium
Gambas version : 3.16
Product : Development Environment
Description
-----------
Process #1, the one that creates the shared memory segment:
int shm_size=1048576; /* was 524288 */
char shm_id[] = {"/SHM_SEG"};
int shm_fd; /* descriptor for shared memory */
void *shm_addr;
shm_fd = shm_open(shm_id, O_CREAT | O_RDWR, 0660);
if (shm_fd == -1)
{
perror("Scanner: open");
exit(-10);
}
/* set the shared memory length. this is necessary, because it defaults to zero! */
ftruncate(shm_fd, shm_size);
/* map shared memory to process address space */
shm_addr = mmap(NULL, shm_size, PROT_READ|PROT_WRITE, MAP_SHARED, shm_fd, 0);
if (shm_addr == MAP_FAILED)
{
perror("Scanner: mmap");
exit(-30);
}
shmaddr2 = (char *)shm_addr; /* tie into existing pointer */
..................................................................................
The second process is the Logger module, which accepts messages from the other modules via queues,
and makes entries in the system log. It connects successfully to the shared memory segment:
int shm_size=1048576; /* was 524288 */
char shm_id[] = {"/SHM_SEG"};
int shm_fd; /* descriptor for shared memory */
void *shm_addr;
shm_fd = shm_open(shm_id, O_RDWR, 0660);
if (shm_fd == -1)
{
perror("open");
exit(-10);
}
/* map shared memory to process address space */
/* void * mmap (void *address, size_t length, int protect, int flags, int filedes, off_t offset) */
shm_addr = mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
if (shm_addr == MAP_FAILED)
{
perror("mmap");
exit(-30);
}
lshmaddr = (char *)shm_addr; /* tie into existing pointer */
.................................................................................
The "scanner" process forks, and starts the "logger". Both processes write a heartbeat to shared memory, among other things.
Now in Gambas, in the Public Sub Form_Open() module...
Dim uidptr As Pointer
Dim protection As Integer
Dim visibility As Integer
Dim buf1 As String
Dim shm_size As Integer = 1048576
Dim shm_fd As Integer
Dim shm_addr As Pointer
Dim shm_id As String = "/SHM_SEG"
Dim vptr As Pointer = Null
Dim mmap_err As Long
protection = 3 ' PROT_READ | PROT_WRITE MAP_FIXED = 16
visibility = 2 ' MAP_SHARED(4) MAP_PRIVATE(2)
shm_fd = shm_open(shm_id, 2, 666) ' 2=read/write
If shm_fd == -1 Then
Message.Info("shm_open() failed!", " OK ")
Quit
Endif
' map shared Memory To process address space
shm_addr = mmap(0, shm_size, protection, visibility, shm_fd, 0)
mmap_err = shm_addr ' convert the pointer to a long
If mmap_err < 1 Then
Message.Info("mmap() failed!", " OK ")
Quit
Endif
shmaddr2 = shm_addr
............................................................
Okay. The first odd thing is, if I set the visibility flag for mmap() to MAP_SHARED, it will error out every time.
If I make the visibility MAP_PRIVATE, now Gambas can see the changing heartbeats from the two local processes, but
when Gambas writes to shared memory, Gambas can see the data, but neither of the local processes sees it.
The shared memory file has the appropriate permissions for both processes, and Gambas, to access it.
Now, in Gambas, I am preserving the shared memory base address by copying it to another pointer, before I add offsets
to it. Thus, I am using @byte, or @Integer to read from shared memory.
To shut down the system, Gambas has a pushbutton, which causes a write to shared memory + 66 of the character "Q". Each
process watches this shared memory location, waiting for a command.
Public Sub btn_killsys_Click()
Dim a As Integer
Dim shmaddr5 As Pointer
Dim SPstream As Stream
shmaddr5 = global.shmaddr
SPstream = Memory shmaddr5 For Write
Message.title = "Shut Down SPOCS"
a = message.Question("Are You Sure?", "YES", "NO")
If a = 1 Then ' yes
Seek #SPstream, +66
Write #SPstream, "Q" ' remember that the stream pointer gets incremented
Message.Info("SPOCS is Shutting Down!", "OK")
Endif
If a = 2 Then ' no
'do nothing
Endif
End
This was the old method, from when I used shmat() to get shared memory. I tried the memory pointer-and-memcpy()
method, but Gambas doesn't see the data. On startup, the "scanner" loads a batch of data from a setup file into shared memory,
and Gambas can see all of that. But when Gambas writes, Gambas sees the data, but the local processes do not.
Any idea on what I am doing incorrectly? Thanks!
System information
------------------
Gambas 3.16.2, Fedora Linux version 35, quad core AMD processor
More information about the Bugtracker
mailing list