00001 #include "gl3HistoManager.h"
00002
00003 #include <rtsLog.h>
00004
00005 #include <errno.h>
00006 #include <netinet/in.h>
00007 #include <unistd.h>
00008 #include <netdb.h>
00009 #include <sys/types.h>
00010 #include <sys/socket.h>
00011 #include <fcntl.h>
00012 #include <string.h>
00013
00014 #include <iostream>
00015
00016 using namespace std;
00017
00018
00019
00020
00021 gl3HistoManager *gl3HistoManager::pinstance = 0;
00022
00023 gl3HistoManager::gl3HistoManager()
00024 {
00025 histoList.clear();
00026
00027 verbosity = warn;
00028 maxBytes = 300000;
00029 }
00030
00031
00032 gl3HistoManager *gl3HistoManager::instance()
00033 {
00034 if (pinstance == 0) {
00035 pinstance = new gl3HistoManager;
00036 }
00037 return pinstance;
00038 }
00039
00040
00041
00042
00043
00044 void gl3HistoManager::add(gl3Histo *histo)
00045 {
00046 histoList.push_back(histo);
00047
00048 if (verbosity >= dbg) {
00049 cout << "gl3HistoManager: Histogram '"
00050 << histo->header.title << "' added." << endl;
00051 }
00052 }
00053
00054 void gl3HistoManager::remove(gl3Histo *histo)
00055 {
00056 histoList.remove(histo);
00057 }
00058
00059
00060 int gl3HistoManager::resetHistos ( ) {
00061 list<gl3Histo*>::iterator histo;
00062 for(histo=histoList.begin(); histo!=histoList.end(); histo++) {
00063 (*histo)->Reset();
00064 }
00065 return 0 ;
00066 }
00067
00068
00069 int gl3HistoManager::saveHistos(char * filename)
00070 {
00071 char* buffer = new char[maxBytes];
00072
00073 int nBytes = writeHistos (buffer) ;
00074
00075 if(verbosity >= dbg)
00076 LOG(ERR, "gl3Conductor::saveHistos: writing to %s\n",
00077 filename,0,0,0,0) ;
00078
00079
00080 if ( nBytes < 0 ) {
00081 if(verbosity >= err)
00082 LOG(ERR, "gl3Conductor::saveHistos: buffer too small\n",0,0,0,0,0);
00083 return 1 ;
00084 }
00085
00086
00087 int fd = open(filename, O_RDWR|O_CREAT, 00644);
00088 if ( fd<0 ) {
00089 if(verbosity >= err)
00090 LOG(ERR, "gl3Conductor::saveHistos: unable to open file %s \n",
00091 filename,0,0,0,0) ;
00092 return 1 ;
00093 }
00094
00095
00096 if (write(fd,buffer,nBytes) != nBytes) {
00097 if(verbosity >= err)
00098 LOG(ERR, "gl3Conductor::saveHistos: write to file %s failed\n",
00099 filename,0,0,0,0) ;
00100 return 1 ;
00101 }
00102
00103 delete[] buffer;
00104
00105 close(fd);
00106
00107 return 0;
00108 }
00109
00110
00111
00112
00113
00114
00115 int gl3HistoManager::listenAtPort(int port)
00116 {
00117 if (is_listening) return 0;
00118
00119 struct sockaddr_in gl3Address;
00120
00121 int backLog = 5 ;
00122
00123 if ((socketFd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
00124 LOG(ERR, "gl3HistoManager::listen: error opening socket: %s\n",
00125 strerror(errno) ,0,0,0,0);
00126 return -1;
00127 }
00128 fcntl(socketFd, F_SETFL, O_NONBLOCK);
00129 int optval = 1;
00130 if(setsockopt(socketFd, SOL_SOCKET,
00131 SO_REUSEADDR, (void *)&optval, sizeof(optval)) == -1) {
00132 LOG(ERR, "gl3HistoManager::listen: setsockopt: %s\n", strerror(errno),0,0,0,0);
00133 return -1;
00134 }
00135
00136
00137 gl3Address.sin_family = AF_INET;
00138 gl3Address.sin_port = htons(port);
00139 gl3Address.sin_addr.s_addr = INADDR_ANY;
00140 bzero(&(gl3Address.sin_zero), 8);
00141
00142
00143 if (bind(socketFd, (struct sockaddr *)&gl3Address,
00144 sizeof(struct sockaddr)) == -1) {
00145 LOG(ERR, "gl3HistoManager::listen: bind: %s\n",strerror(errno) ,0,0,0,0);
00146 return -1;
00147 }
00148
00149 if (listen(socketFd, backLog) == -1) {
00150 LOG(ERR, "gl3HistoManager::listen: listen: %s\n",strerror(errno) ,0,0,0,0);
00151 return -1;
00152 }
00153
00154 is_listening = true;
00155 return 0 ;
00156 }
00157
00158
00159 int gl3HistoManager::checkRequest ( ) {
00160
00161 struct sockaddr_in remoteAddress;
00162 socklen_t sin_size = sizeof(struct sockaddr_in);
00163
00164 if ((remoteSocket = accept(socketFd, (struct sockaddr *)&remoteAddress,
00165 &sin_size)) == -1) {
00166 return 0;
00167 }
00168
00169
00170 char* buffer = new char[maxBytes];
00171
00172 int nBytes = writeHistos(buffer) ;
00173
00174 if ( nBytes < 0 ) {
00175 LOG(ERR, "gl3Conductor::checkHistoRequest: buffer too small \n ",0,0,0,0,0 );
00176 return 1 ;
00177 }
00178 int nSend = send(remoteSocket, buffer, nBytes, 0 ) ;
00179 LOG(ERR, "gl3Conductor: %d out of %d bytes sent\n ", nSend, nBytes ,0,0,0) ;
00180 if ( nSend == -1) {
00181 perror("send");
00182 return 1 ;
00183 }
00184 delete []buffer ;
00185
00186 return 0 ;
00187 }
00188
00189
00190
00191
00192
00193
00194 int gl3HistoManager::writeHistos (char *buffer){
00195
00196
00197
00198 int runNumber = -1;
00199
00200
00201
00202 gl3HistoContainer* container = (gl3HistoContainer *)buffer ;
00203 container->runNumber = runNumber ;
00204 container->nHistos = histoList.size();
00205
00206 char* pointer = (char *)&(container->buffer) ;
00207 char* endBuffer = buffer + maxBytes ;
00208 int nBytes ;
00209 int nTotalBytes = sizeof(gl3HistoContainer) - sizeof(int);
00210
00211 list<gl3Histo*>::iterator histo;
00212 for(histo=histoList.begin(); histo!=histoList.end(); histo++) {
00213
00214 if (verbosity >= dbg) {
00215 cout << "gl3HistoManager: Histogram '"
00216 << (*histo)->header.title << "' added." << endl;
00217 }
00218
00219 nBytes = (*histo)->Write ( endBuffer-pointer, pointer ) ;
00220 if ( nBytes <= 0 ) {
00221
00222 LOG(ERR, "gl3Container::writeHistos: buffer too short (%d bytes)\n",
00223 maxBytes,0,0,0,0) ;
00224 return 0 ;
00225 }
00226 nTotalBytes += nBytes ;
00227 if ( nTotalBytes > maxBytes ) {
00228 LOG(ERR, "gl3HistoManager::writeHistos: nTotalBytes %d max %d\n",
00229 nTotalBytes, maxBytes,0,0,0 ) ;
00230 return -1 ;
00231 }
00232 pointer += nBytes * sizeof(char) ;
00233 }
00234 container->nBytes = nTotalBytes ;
00235 if(verbosity >= note) {
00236 LOG(ERR, "gl3HistoManager::writeHistos: histos %d Bytes %d \n",
00237 histoList.size(), nTotalBytes ,0,0,0) ;
00238 }
00239
00240 return nTotalBytes ;
00241 }