forked from enlightenment/efl
248 lines
5.5 KiB
C
248 lines
5.5 KiB
C
#include "config.h"
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/un.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
|
|
#include <Eina.h>
|
|
|
|
#include "evas_cs2.h"
|
|
|
|
static int socketfd = -1;
|
|
static unsigned int _rid_count = 1;
|
|
static int _evas_cserve2_usage_log_dom = -1;
|
|
|
|
static struct sockaddr_un socksize;
|
|
#ifndef UNIX_PATH_MAX
|
|
#define UNIX_PATH_MAX sizeof(socksize.sun_path)
|
|
#endif
|
|
|
|
#ifdef ERR
|
|
#undef ERR
|
|
#endif
|
|
#define ERR(...) EINA_LOG_DOM_ERR(_evas_cserve2_usage_log_dom, __VA_ARGS__)
|
|
#ifdef DBG
|
|
#undef DBG
|
|
#endif
|
|
#define DBG(...) EINA_LOG_DOM_DBG(_evas_cserve2_usage_log_dom, __VA_ARGS__)
|
|
#ifdef WRN
|
|
#undef WRN
|
|
#endif
|
|
#define WRN(...) EINA_LOG_DOM_WARN(_evas_cserve2_usage_log_dom, __VA_ARGS__)
|
|
#ifdef INF
|
|
#undef INF
|
|
#endif
|
|
#define INF(...) EINA_LOG_DOM_INFO(_evas_cserve2_usage_log_dom, __VA_ARGS__)
|
|
|
|
static void
|
|
_socket_path_set(char *path)
|
|
{
|
|
char *env;
|
|
char buf[UNIX_PATH_MAX];
|
|
|
|
env = getenv("EVAS_CSERVE2_SOCKET");
|
|
if (env && env[0])
|
|
{
|
|
strncpy(path, env, UNIX_PATH_MAX - 1);
|
|
return;
|
|
}
|
|
|
|
snprintf(buf, sizeof(buf), "/tmp/.evas-cserve2-%x.socket", (int)getuid());
|
|
/* FIXME: check we can actually create this socket */
|
|
strcpy(path, buf);
|
|
}
|
|
|
|
static Eina_Bool
|
|
_server_connect(void)
|
|
{
|
|
int s, len;
|
|
struct sockaddr_un remote;
|
|
|
|
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
|
|
{
|
|
ERR("socket");
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
remote.sun_family = AF_UNIX;
|
|
_socket_path_set(remote.sun_path);
|
|
len = strlen(remote.sun_path) + sizeof(remote.sun_family);
|
|
if (connect(s, (struct sockaddr *)&remote, len) == -1)
|
|
{
|
|
ERR("connect");
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
fcntl(s, F_SETFL, O_NONBLOCK);
|
|
|
|
socketfd = s;
|
|
|
|
DBG("connected to cserve2 server.");
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
static void
|
|
_server_disconnect(void)
|
|
{
|
|
close(socketfd);
|
|
socketfd = -1;
|
|
}
|
|
|
|
static Eina_Bool
|
|
_server_send(const void *data, int size)
|
|
{
|
|
int sent = 0;
|
|
ssize_t ret;
|
|
const char *msg = data;
|
|
|
|
while (sent < size)
|
|
{
|
|
ret = send(socketfd, msg + sent, size - sent, MSG_NOSIGNAL);
|
|
if (ret < 0)
|
|
{
|
|
if ((errno == EAGAIN) || (errno == EINTR))
|
|
continue;
|
|
return EINA_FALSE;
|
|
}
|
|
sent += ret;
|
|
}
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
static int sr_size = 0;
|
|
static int sr_got = 0;
|
|
static char *sr_buf = NULL;
|
|
|
|
static void *
|
|
_server_read(int *size)
|
|
{
|
|
int n;
|
|
void *ret;
|
|
|
|
if (sr_size)
|
|
goto get_data;
|
|
|
|
n = recv(socketfd, &sr_size, sizeof(sr_size), 0);
|
|
if (n < 0)
|
|
return NULL;
|
|
|
|
sr_buf = malloc(sr_size);
|
|
|
|
get_data:
|
|
n = recv(socketfd, sr_buf + sr_got, sr_size - sr_got, 0);
|
|
if (n < 0)
|
|
return NULL;
|
|
|
|
sr_got += n;
|
|
if (sr_got < sr_size)
|
|
return NULL;
|
|
|
|
*size = sr_size;
|
|
sr_size = 0;
|
|
sr_got = 0;
|
|
ret = sr_buf;
|
|
sr_buf = NULL;
|
|
|
|
return ret;
|
|
}
|
|
|
|
static void
|
|
_usage_msg_send(void)
|
|
{
|
|
Msg_Base msg;
|
|
int size;
|
|
|
|
memset(&msg, 0, sizeof(msg));
|
|
msg.type = CSERVE2_STATS;
|
|
msg.rid = _rid_count++;
|
|
|
|
size = sizeof(msg);
|
|
|
|
if (!_server_send(&size, sizeof(size)))
|
|
{
|
|
ERR("Could not send usage msg size to server.");
|
|
return;
|
|
}
|
|
if (!_server_send(&msg, size))
|
|
{
|
|
ERR("Could not send usage msg body to server.");
|
|
return;
|
|
}
|
|
}
|
|
|
|
static void
|
|
_usage_msg_read(void)
|
|
{
|
|
Msg_Stats *msg = NULL;
|
|
int size;
|
|
|
|
printf("Requesting server statistics.\n\n");
|
|
while (!msg)
|
|
msg = _server_read(&size);
|
|
|
|
if (msg->base.type != CSERVE2_STATS)
|
|
{
|
|
ERR("Invalid message received from server."
|
|
"Something went badly wrong.");
|
|
return;
|
|
}
|
|
|
|
printf("Printing server usage.\n");
|
|
printf("======================\n\n");
|
|
printf("\nImage Usage Statistics:\n");
|
|
printf("----------------------\n\n");
|
|
printf("Image headers usage: %d bytes\n", msg->images.files_size);
|
|
printf("Image data requested: %d kbytes\n", msg->images.requested_size / 1024);
|
|
printf("Image data usage: %d kbytes\n", msg->images.images_size / 1024);
|
|
printf("Image data unused: %d kbytes\n", msg->images.unused_size / 1024);
|
|
printf("Image headers load time: %dus\n", msg->images.files_load_time);
|
|
printf("Image headers saved time: %dus\n", msg->images.files_saved_time);
|
|
printf("Image data load time: %dus\n", msg->images.images_load_time);
|
|
printf("Image data saved time: %dus\n", msg->images.images_saved_time);
|
|
printf("\nFont Usage Statistics:\n");
|
|
printf("----------------------\n\n");
|
|
printf("Requested usage: %d bytes\n", msg->fonts.requested_size);
|
|
printf("Real usage: %d bytes\n", msg->fonts.real_size);
|
|
printf("Unused size: %d bytes\n", msg->fonts.unused_size);
|
|
printf("Fonts load time: %dus\n", msg->fonts.fonts_load_time);
|
|
printf("Fonts used load time: %dus\n", msg->fonts.fonts_used_load_time);
|
|
printf("Fonts used saved time: %dus\n", msg->fonts.fonts_used_saved_time);
|
|
printf("Glyphs load time: %dus\n", msg->fonts.glyphs_load_time);
|
|
printf("Glyphs render time: %dus\n", msg->fonts.glyphs_render_time);
|
|
printf("Glyphs saved time: %dus\n", msg->fonts.glyphs_saved_time);
|
|
printf("Glyphs request time: %dus\n", msg->fonts.glyphs_request_time);
|
|
printf("Glyphs slave time: %dus\n", msg->fonts.glyphs_slave_time);
|
|
|
|
printf("\n");
|
|
}
|
|
|
|
int
|
|
main(void)
|
|
{
|
|
eina_init();
|
|
|
|
_evas_cserve2_usage_log_dom = eina_log_domain_register
|
|
("evas_cserve2_usage", EINA_COLOR_BLUE);
|
|
|
|
if (!_server_connect())
|
|
{
|
|
ERR("Could not connect to server.");
|
|
return -1;
|
|
}
|
|
|
|
_usage_msg_send();
|
|
|
|
_usage_msg_read();
|
|
|
|
_server_disconnect();
|
|
|
|
eina_shutdown();
|
|
}
|