969182479cbbefa76769411b8f2567c09dd1b559
[profile/ivi/evas.git] / src / bin / evas_cserve2_usage.c
1 #include "config.h"
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <errno.h>
6 #include <string.h>
7 #include <sys/types.h>
8 #include <sys/socket.h>
9 #include <sys/un.h>
10 #include <unistd.h>
11 #include <fcntl.h>
12
13 #include <Eina.h>
14
15 #include "evas_cs2.h"
16
17 static int socketfd = -1;
18 static unsigned int _rid_count = 1;
19 static int _evas_cserve2_usage_log_dom = -1;
20
21 static struct sockaddr_un socksize;
22 #ifndef UNIX_PATH_MAX
23 #define UNIX_PATH_MAX sizeof(socksize.sun_path)
24 #endif
25
26 #ifdef ERR
27 #undef ERR
28 #endif
29 #define ERR(...) EINA_LOG_DOM_ERR(_evas_cserve2_usage_log_dom, __VA_ARGS__)
30 #ifdef DBG
31 #undef DBG
32 #endif
33 #define DBG(...) EINA_LOG_DOM_DBG(_evas_cserve2_usage_log_dom, __VA_ARGS__)
34 #ifdef WRN
35 #undef WRN
36 #endif
37 #define WRN(...) EINA_LOG_DOM_WARN(_evas_cserve2_usage_log_dom, __VA_ARGS__)
38 #ifdef INF
39 #undef INF
40 #endif
41 #define INF(...) EINA_LOG_DOM_INFO(_evas_cserve2_usage_log_dom, __VA_ARGS__)
42
43 static void
44 _socket_path_set(char *path)
45 {
46    char *env;
47    char buf[UNIX_PATH_MAX];
48
49    env = getenv("EVAS_CSERVE2_SOCKET");
50    if (env && env[0])
51      {
52         strncpy(path, env, UNIX_PATH_MAX - 1);
53         return;
54      }
55
56    snprintf(buf, sizeof(buf), "/tmp/.evas-cserve2-%x.socket", (int)getuid());
57    /* FIXME: check we can actually create this socket */
58    strcpy(path, buf);
59 }
60
61 static Eina_Bool
62 _server_connect(void)
63 {
64    int s, len;
65    struct sockaddr_un remote;
66
67    if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
68      {
69         ERR("socket");
70         return EINA_FALSE;
71      }
72
73    remote.sun_family = AF_UNIX;
74    _socket_path_set(remote.sun_path);
75    len = strlen(remote.sun_path) + sizeof(remote.sun_family);
76    if (connect(s, (struct sockaddr *)&remote, len) == -1)
77      {
78         ERR("connect");
79         return EINA_FALSE;
80      }
81
82    fcntl(s, F_SETFL, O_NONBLOCK);
83
84    socketfd = s;
85
86    DBG("connected to cserve2 server.");
87    return EINA_TRUE;
88 }
89
90 static void
91 _server_disconnect(void)
92 {
93    close(socketfd);
94    socketfd = -1;
95 }
96
97 static Eina_Bool
98 _server_send(const void *data, int size)
99 {
100    int sent = 0;
101    ssize_t ret;
102    const char *msg = data;
103
104    while (sent < size)
105      {
106         ret = send(socketfd, msg + sent, size - sent, MSG_NOSIGNAL);
107         if (ret < 0)
108           {
109              if ((errno == EAGAIN) || (errno == EINTR))
110                continue;
111              return EINA_FALSE;
112           }
113         sent += ret;
114      }
115
116    return EINA_TRUE;
117 }
118
119 static int sr_size = 0;
120 static int sr_got = 0;
121 static char *sr_buf = NULL;
122
123 static void *
124 _server_read(int *size)
125 {
126    int n;
127    void *ret;
128
129    if (sr_size)
130      goto get_data;
131
132    n = recv(socketfd, &sr_size, sizeof(sr_size), 0);
133    if (n < 0)
134      return NULL;
135
136    sr_buf = malloc(sr_size);
137
138 get_data:
139    n = recv(socketfd, sr_buf + sr_got, sr_size - sr_got, 0);
140    if (n < 0)
141      return NULL;
142
143    sr_got += n;
144    if (sr_got < sr_size)
145      return NULL;
146
147    *size = sr_size;
148    sr_size = 0;
149    sr_got = 0;
150    ret = sr_buf;
151    sr_buf = NULL;
152
153    return ret;
154 }
155
156 static void
157 _usage_msg_send(void)
158 {
159    Msg_Base msg;
160    int size;
161
162    memset(&msg, 0, sizeof(msg));
163    msg.type = CSERVE2_STATS;
164    msg.rid = _rid_count++;
165
166    size = sizeof(msg);
167
168    if (!_server_send(&size, sizeof(size)))
169      {
170         ERR("Could not send usage msg size to server.");
171         return;
172      }
173    if (!_server_send(&msg, size))
174      {
175         ERR("Could not send usage msg body to server.");
176         return;
177      }
178 }
179
180 static void
181 _usage_msg_read(void)
182 {
183    Msg_Stats *msg = NULL;
184    int size;
185
186    printf("Requesting server statistics.\n\n");
187    while (!msg)
188      msg = _server_read(&size);
189
190    if (msg->base.type != CSERVE2_STATS)
191      {
192         ERR("Invalid message received from server."
193             "Something went badly wrong.");
194         return;
195      }
196
197    printf("Printing server usage.\n");
198    printf("======================\n\n");
199    printf("\nImage Usage Statistics:\n");
200    printf("----------------------\n\n");
201    printf("Image headers usage: %d bytes\n", msg->images.files_size);
202    printf("Image data requested: %d kbytes\n", msg->images.requested_size / 1024);
203    printf("Image data usage: %d kbytes\n", msg->images.images_size / 1024);
204    printf("Image data unused: %d kbytes\n", msg->images.unused_size / 1024);
205    printf("Image headers load time: %dus\n", msg->images.files_load_time);
206    printf("Image headers saved time: %dus\n", msg->images.files_saved_time);
207    printf("Image data load time: %dus\n", msg->images.images_load_time);
208    printf("Image data saved time: %dus\n", msg->images.images_saved_time);
209    printf("\nFont Usage Statistics:\n");
210    printf("----------------------\n\n");
211    printf("Requested usage: %d bytes\n", msg->fonts.requested_size);
212    printf("Real usage: %d bytes\n", msg->fonts.real_size);
213    printf("Unused size: %d bytes\n", msg->fonts.unused_size);
214    printf("Fonts load time: %dus\n", msg->fonts.fonts_load_time);
215    printf("Fonts used load time: %dus\n", msg->fonts.fonts_used_load_time);
216    printf("Fonts used saved time: %dus\n", msg->fonts.fonts_used_saved_time);
217    printf("Glyphs load time: %dus\n", msg->fonts.glyphs_load_time);
218
219    printf("\n");
220 }
221
222 int
223 main(void)
224 {
225    eina_init();
226
227    _evas_cserve2_usage_log_dom = eina_log_domain_register
228       ("evas_cserve2_usage", EINA_COLOR_BLUE);
229
230    if (!_server_connect())
231      {
232         ERR("Could not connect to server.");
233         return -1;
234      }
235
236    _usage_msg_send();
237
238    _usage_msg_read();
239
240    _server_disconnect();
241
242    eina_shutdown();
243 }