c873a1d243b809827baab1f627e26a243e0814bd
[mono.git] / mono / mini / wapihandles.c
1 #include <config.h>
2 #include <glib.h>
3
4 #include "mini.h"
5
6 #if defined(HOST_WIN32) || !defined(HAVE_SYS_IPC_H) || !defined(HAVE_SYS_SEM_H)
7
8 int mini_wapi_hps (int argc, char **argv)
9 {
10         return 0;
11 }
12
13 int mini_wapi_semdel (int argc, char **argv)
14 {
15         return 0;
16 }
17
18 int mini_wapi_seminfo (int argc, char **argv)
19 {
20         return 0;
21 }
22
23 #else
24
25 #include <errno.h>
26 #include <sys/types.h>
27 #include <sys/ipc.h>
28 #include <sys/sem.h>
29 #include <mono/io-layer/io-layer.h>
30
31 /* We're digging into handle internals here... */
32 #include <mono/io-layer/handles-private.h>
33 #include <mono/io-layer/wapi-private.h>
34 #include <mono/io-layer/shared.h>
35 #include <mono/io-layer/collection.h>
36
37 static const gchar *unused_details (struct _WapiHandleShared *handle);
38 static const gchar *unshared_details (struct _WapiHandleShared *handle);
39 #if 0
40 static const gchar *thread_details (struct _WapiHandleShared *handle);
41 #endif
42 static const gchar *namedmutex_details (struct _WapiHandleShared *handle);
43 static const gchar *namedsem_details (struct _WapiHandleShared *handle);
44 static const gchar *namedevent_details (struct _WapiHandleShared *handle);
45 static const gchar *process_details (struct _WapiHandleShared *handle);
46
47 /* This depends on the ordering of the enum WapiHandleType in
48  * io-layer/wapi-private.h
49  */
50 static const gchar * (*details[])(struct _WapiHandleShared *)=
51 {
52         unused_details,
53         unshared_details,               /* file */
54         unshared_details,               /* console */
55         unshared_details,               /* thread */
56         unshared_details,               /* sem */
57         unshared_details,               /* mutex */
58         unshared_details,               /* event */
59         unshared_details,               /* socket */
60         unshared_details,               /* find */
61         process_details,
62         unshared_details,               /* pipe */
63         namedmutex_details,
64         namedsem_details,
65         namedevent_details,
66         unused_details,
67 };
68
69 int mini_wapi_hps (int argc, char **argv)
70 {
71         guint32 i;
72         guint32 now;
73
74         _wapi_shared_layout = _wapi_shm_attach(WAPI_SHM_DATA);
75         if (_wapi_shared_layout == NULL) {
76                 g_error ("Failed to attach shared memory!");
77                 exit (-1);
78         }
79
80         _wapi_fileshare_layout = _wapi_shm_attach(WAPI_SHM_FILESHARE);
81         if (_wapi_fileshare_layout == NULL) {
82                 g_error ("Failed to attach fileshare shared memory!");
83                 exit (-1);
84         }
85         
86         if (argc > 1) {
87                 _wapi_shm_semaphores_init ();
88                 _wapi_collection_init ();
89                 _wapi_handle_collect ();
90         }
91         
92         g_print ("collection: %d sem: 0x%x\n",
93                  _wapi_shared_layout->collection_count,
94                  _wapi_shared_layout->sem_key);
95         
96         now = (guint32)(time(NULL) & 0xFFFFFFFF);
97         for (i = 0; i < _WAPI_HANDLE_INITIAL_COUNT; i++) {
98                 struct _WapiHandleShared *shared;
99                 
100                 shared = &_wapi_shared_layout->handles[i];
101                 if (shared->type != WAPI_HANDLE_UNUSED) {
102                         g_print ("%3x (%3d) [%7s] %4u %s (%s)\n",
103                                  i, shared->handle_refs,
104                                  _wapi_handle_typename[shared->type],
105                                  now - shared->timestamp,
106                                  shared->signalled?"Sg":"Un",
107                                  details[shared->type](shared));
108                 }
109         }
110
111         g_print ("Fileshare hwm: %d\n", _wapi_fileshare_layout->hwm);
112         
113         for (i = 0; i <= _wapi_fileshare_layout->hwm; i++) {
114                 struct _WapiFileShare *file_share;
115                 
116                 file_share = &_wapi_fileshare_layout->share_info[i];
117                 if (file_share->handle_refs > 0) {
118                         g_print ("dev: 0x%llx ino: %lld open pid: %d share: 0x%x access: 0x%x refs: %d\n", (long long int)file_share->device, (long long int)file_share->inode, file_share->opened_by_pid, file_share->sharemode, file_share->access, file_share->handle_refs);
119                 }
120         }
121         
122         exit (0);
123 }
124
125 static const gchar *unused_details (struct _WapiHandleShared *handle)
126 {
127         return("unused details");
128 }
129
130 static const gchar *unshared_details (struct _WapiHandleShared *handle)
131 {
132         return("unshared details");
133 }
134
135 #if 0
136 static const gchar *thread_details (struct _WapiHandleShared *handle)
137 {
138         static gchar buf[80];
139         struct _WapiHandle_thread *thr=&handle->u.thread;
140
141         g_snprintf (buf, sizeof(buf),
142                     "proc: %d, tid: %ld, state: %d, exit: %u, join: %d",
143                     thr->owner_pid, thr->id, thr->state, thr->exitstatus,
144                     thr->joined);
145         
146         return(buf);
147 }
148 #endif
149
150 static const gchar *namedmutex_details (struct _WapiHandleShared *handle)
151 {
152         static gchar buf[80];
153         gchar *name;
154         struct _WapiHandle_namedmutex *mut=&handle->u.namedmutex;
155         
156         name = mut->sharedns.name;
157         
158         g_snprintf (buf, sizeof(buf), "[%15s] own: %5d:%5ld, count: %5u",
159                     name==NULL?(gchar *)"":name, mut->pid, mut->tid,
160                     mut->recursion);
161
162         return(buf);
163 }
164
165 static const gchar *namedsem_details (struct _WapiHandleShared *handle)
166 {
167         static gchar buf[80];
168         gchar *name;
169         struct _WapiHandle_namedsem *sem = &handle->u.namedsem;
170         
171         name = sem->sharedns.name;
172         
173         g_snprintf (buf, sizeof(buf), "[%15s] val: %5u, max: %5d",
174                     name == NULL?(gchar *)"":name, sem->val, sem->max);
175
176         return(buf);
177 }
178
179 static const gchar *namedevent_details (struct _WapiHandleShared *handle)
180 {
181         static gchar buf[80];
182         gchar *name;
183         struct _WapiHandle_namedevent *event = &handle->u.namedevent;
184         
185         name = event->sharedns.name;
186         
187         g_snprintf (buf, sizeof(buf), "[%15s] %s count: %5u",
188                     name == NULL?(gchar *)"":name,
189                     event->manual?"Manual":"Auto", event->set_count);
190
191         return(buf);
192 }
193
194 static const gchar *process_details (struct _WapiHandleShared *handle)
195 {
196         static gchar buf[80];
197         gchar *name;
198         struct _WapiHandle_process *proc=&handle->u.process;
199         
200         name = proc->proc_name;
201         
202         g_snprintf (buf, sizeof(buf), "[%25.25s] pid: %5u exit: %u",
203                     name==NULL?(gchar *)"":name, proc->id, proc->exitstatus);
204         
205         return(buf);
206 }
207
208 /* The old handles/semdel.c */
209 int mini_wapi_semdel (int argc, char **argv)
210 {
211         int sem_id, ret;
212         
213         _wapi_shared_layout = _wapi_shm_attach(WAPI_SHM_DATA);
214         if (_wapi_shared_layout == FALSE ||
215             _wapi_shared_layout->sem_key == 0) {
216                 exit (0);
217         }
218
219         sem_id = semget (_wapi_shared_layout->sem_key, _WAPI_SHARED_SEM_COUNT, 0600);
220         if (sem_id != -1) {
221                 ret = semctl (sem_id, 0, IPC_RMID);
222                 if (ret == -1) {
223                         g_message ("Error deleting semaphore: %s",
224                                    g_strerror (errno));
225                 }
226         }
227         
228         exit (0);
229 }
230
231 static void sem_explain (int sem_id, ushort *vals, int which)
232 {
233         pid_t pid;
234         
235         g_print ("%d ", vals[which]);
236         if (vals[which] >= 1) {
237                 g_print ("(Unlocked)");
238         } else {
239                 pid = semctl (sem_id, which, GETPID);
240                 
241                 g_print ("(Locked by %d)", pid);
242         }
243         g_print ("\n");
244 }
245
246 int mini_wapi_seminfo (int argc, char **argv)
247 {
248         int sem_id, ret;
249         union semun
250         {
251                 int val;
252                 struct semid_ds *buf;
253                 ushort *array;
254         } arg;
255         ushort vals[_WAPI_SHARED_SEM_COUNT];
256         
257         _wapi_shared_layout = _wapi_shm_attach (WAPI_SHM_DATA);
258         if (_wapi_shared_layout == FALSE ||
259             _wapi_shared_layout->sem_key == 0) {
260                 exit (0);
261         }
262         
263         sem_id = semget (_wapi_shared_layout->sem_key, _WAPI_SHARED_SEM_COUNT, 0600);
264         if (sem_id != -1) {
265                 g_print ("Getting values for sem: 0x%x\n",
266                          _wapi_shared_layout->sem_key);
267                 arg.array = vals;
268                 ret = semctl (sem_id, 0, GETALL, arg);
269                 if (ret != -1) {
270                         g_print ("Namespace: ");
271                         sem_explain (sem_id, vals, _WAPI_SHARED_SEM_NAMESPACE);
272                         g_print ("Fileshare: ");
273                         sem_explain (sem_id, vals, _WAPI_SHARED_SEM_FILESHARE);
274                         g_print ("Handles: ");
275                         sem_explain (sem_id, vals,
276                                      _WAPI_SHARED_SEM_SHARED_HANDLES);
277                         g_print ("Count lock: ");
278                         sem_explain (sem_id, vals,
279                                      _WAPI_SHARED_SEM_PROCESS_COUNT_LOCK);
280                         g_print ("Count: %d\n",
281                                  vals[_WAPI_SHARED_SEM_PROCESS_COUNT]);
282                 }
283         }
284         
285         exit (0);
286 }
287
288 #endif
289