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 
36 #include <errno.h>
37 #include <iostream>
38 #include <signal.h>
39 
40 using namespace std;
41 using namespace fawkes;
42 
43 #define SHMEM_SIZE 2048
44 #define SHMEM_TOKEN "JustSomeDumbQA"
45 
46 typedef struct
47 {
48  void *ptr;
49 } header_t;
50 
51 bool quit = false;
52 
53 void
54 signal_handler(int signum)
55 {
56  quit = true;
57 }
58 
59 int
60 main(int argc, char **argv)
61 {
62  signal(SIGINT, signal_handler);
63 
64  key_t key = ftok(".", 'b');
65  printf("Key: 0x%x\n", key);
66 
67  if (argc == 1) {
68  // master
69  int shmid = shmget(key, SHMEM_SIZE, IPC_CREAT | 0666);
70  if (shmid == -1) {
71  perror("M: Could not get ID");
72  exit(1);
73  }
74 
75  void *shmem = shmat(shmid, NULL, 0);
76  if (shmem == (void *)-1) {
77  perror("M: Could not attach");
78  exit(2);
79  }
80 
81  memset(shmem, 0, SHMEM_SIZE);
82 
83  header_t *header = (header_t *)shmem;
84  header->ptr = shmem;
85 
86  printf("M: ptr=0x%lx\n", (long unsigned int)shmem);
87 
88  while (!quit) {
89  usleep(100000);
90  }
91 
92  shmctl(shmid, IPC_RMID, NULL);
93  shmdt(shmem);
94 
95  } else {
96  // slave
97  int shmid = shmget(key, SHMEM_SIZE, 0);
98 
99  if (shmid == -1) {
100  perror("S: Could not get ID");
101  exit(1);
102  }
103 
104  void *shmem = shmat(shmid, NULL, 0);
105  if (shmem == (void *)-1) {
106  perror("S: Could not attach");
107  exit(2);
108  }
109 
110  header_t *header = (header_t *)shmem;
111 
112  printf("S: ptr=0x%lx header->ptr=0x%lx\n",
113  (long unsigned int)shmem,
114  (long unsigned int)header->ptr);
115 
116  if (shmem != header->ptr) {
117  printf("S: pointers differ, re-attaching\n");
118  void *ptr = header->ptr;
119  shmdt(shmem);
120  shmem = shmat(shmid, ptr, SHM_REMAP);
121  if (shmem == (void *)-1) {
122  perror("S: Could not re-attach");
123  exit(3);
124  }
125  header = (header_t *)shmem;
126  printf("S: after re-attach: ptr=0x%lx header->ptr=0x%lx\n",
127  (long unsigned int)shmem,
128  (long unsigned int)header->ptr);
129  }
130 
131  /*
132  while ( ! quit ) {
133  usleep(100000);
134  }
135  */
136 
137  shmdt(shmem);
138  }
139 
140  return 0;
141 }
142 
143 /// @endcond
fawkes
Fawkes library namespace.