#include "config.h" #include #include #include #include #include #include #include #include #include #include #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(); return 0; }