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