Fawkes API  Fawkes Development Version
qa_ipc_shmem_lowlevel.cpp
1 
2 /***************************************************************************
3  * qa_ipc_shmem_lowlevel.cpp - lowlevel shared memory qa
4  *
5  * Generated: Sun Oct 22 23:43:36 2006
6  * Copyright 2006 Tim Niemueller [www.niemueller.de]
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version. A runtime exception applies to
14  * this software (see LICENSE.GPL_WRE file mentioned below for details).
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Library General Public License for more details.
20  *
21  * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
22  */
23 
24 /// @cond QA
25 
26 /* This program reveals a problem with the shmat shmaddr parameter. It shows
27  * that this cannot be reliably used to map the shared memory to a specific
28  * address even if the REMAP flag has been set. Maybe this just shows a fundamental
29  * misunderstanding on my side. Have to study more literature, kernel source did
30  * not reveal the problem in an obvious manner to me.
31  */
32 
33 #include <sys/ipc.h>
34 #include <sys/shm.h>
35 #include <errno.h>
36 #include <iostream>
37 #include <signal.h>
38 
39 using namespace std;
40 using namespace fawkes;
41 
42 #define SHMEM_SIZE 2048
43 #define SHMEM_TOKEN "JustSomeDumbQA"
44 
45 typedef struct {
46  void *ptr;
47 } header_t;
48 
49 bool quit = false;
50 
51 void
52 signal_handler(int signum)
53 {
54  quit = true;
55 }
56 
57 int
58 main(int argc, char **argv)
59 {
60 
61  signal(SIGINT, signal_handler);
62 
63  key_t key = ftok(".", 'b');
64  printf("Key: 0x%x\n", key);
65 
66  if ( argc == 1 ) {
67  // master
68  int shmid = shmget(key, SHMEM_SIZE, IPC_CREAT | 0666);
69  if ( shmid == -1 ) {
70  perror("M: Could not get ID");
71  exit(1);
72  }
73 
74  void *shmem = shmat(shmid, NULL, 0);
75  if ( shmem == (void *)-1 ) {
76  perror("M: Could not attach");
77  exit(2);
78  }
79 
80  memset(shmem, 0, SHMEM_SIZE);
81 
82  header_t *header = (header_t *)shmem;
83  header->ptr = shmem;
84 
85  printf("M: ptr=0x%lx\n", (long unsigned int)shmem);
86 
87  while ( ! quit ) {
88  usleep(100000);
89  }
90 
91  shmctl(shmid, IPC_RMID, NULL);
92  shmdt(shmem);
93 
94  } else {
95  // slave
96  int shmid = shmget(key, SHMEM_SIZE, 0);
97 
98  if ( shmid == -1 ) {
99  perror("S: Could not get ID");
100  exit(1);
101  }
102 
103  void *shmem = shmat(shmid, NULL, 0);
104  if ( shmem == (void *)-1 ) {
105  perror("S: Could not attach");
106  exit(2);
107  }
108 
109  header_t *header = (header_t *)shmem;
110 
111  printf("S: ptr=0x%lx header->ptr=0x%lx\n", (long unsigned int)shmem,
112  (long unsigned int)header->ptr);
113 
114  if ( shmem != header->ptr ) {
115  printf("S: pointers differ, re-attaching\n");
116  void *ptr = header->ptr;
117  shmdt(shmem);
118  shmem = shmat(shmid, ptr, SHM_REMAP);
119  if ( shmem == (void *)-1 ) {
120  perror("S: Could not re-attach");
121  exit(3);
122  }
123  header = (header_t *)shmem;
124  printf("S: after re-attach: ptr=0x%lx header->ptr=0x%lx\n",
125  (long unsigned int)shmem, (long unsigned int)header->ptr);
126  }
127 
128  /*
129  while ( ! quit ) {
130  usleep(100000);
131  }
132  */
133 
134  shmdt(shmem);
135  }
136 
137  return 0;
138 }
139 
140 /// @endcond
Fawkes library namespace.
STL namespace.