void* inputreader_thread(void* arg) { for(;;) { char* s = readAuditStream(); if(s == NULL) { LOGERR("Input Stream error"); return NULL; } unsigned int ssize = strlen(s) + 1; if (event_buffer[event_buffer_end].buffer_length < ssize) { if (event_buffer[event_buffer_end].data == NULL) event_buffer[event_buffer_end].data = malloc(ssize); else event_buffer[event_buffer_end].data = realloc(event_buffer[event_buffer_end].data, ssize); if (event_buffer[event_buffer_end].data == NULL) { LOGERR("Unable to allocate memory. Exiting"); return NULL; } event_buffer[event_buffer_end].buffer_length = ssize; } strcpy(event_buffer[event_buffer_end].data, s); pthread_mutex_lock(&mutex); event_buffer_end = ++event_buffer_end % MAX_EVENTS; int start_end_diff = event_buffer_end - event_buffer_start; int blog = backlog(); pthread_cond_signal(&cond); pthread_mutex_unlock(&mutex); if( start_end_diff == 0 ) { // Out of memory LOGERR("Out of memory!"); return NULL; } if (blog > 0 && blog % 100 == 0) LOGD("Backlog %d: %d - %d", blog, event_buffer_start, event_buffer_end); } return NULL; }
void thread_loop(AppData& app_data, CommonData& common, x11::Display& display, glx::Context& context) { Context gl; ResourceAllocator alloc; RaytraceCopier::Params rtc_params( display, context, common.context ); RaytraceCopier rt_copier(app_data, common.rt_target); RaytracerResources rt_res(app_data, common.rt_data, alloc); Raytracer raytracer(app_data, rt_res); raytracer.Use(app_data); std::vector<unsigned> backlog(app_data.cols()); std::chrono::milliseconds bl_interval(100); while(!common.Done()) { // all threads must wait until // the raytrace target is cleared common.master_ready.Wait(); if(common.Done()) break; raytracer.InitFrame(app_data, common.Face()); auto bl_begin = std::chrono::steady_clock::now(); unsigned tile = 0; while(common.NextFaceTile(tile)) { raytracer.Raytrace(app_data, tile); backlog.push_back(tile); auto now = std::chrono::steady_clock::now(); if(bl_begin + bl_interval < now) { gl.Finish(); auto lock = common.Lock(); for(unsigned bl_tile : backlog) { rt_copier.Copy( app_data, rtc_params, raytracer, bl_tile ); } lock.unlock(); backlog.clear(); bl_begin = now; } else gl.Finish(); } auto lock = common.Lock(); for(unsigned bl_tile : backlog) { rt_copier.Copy( app_data, rtc_params, raytracer, bl_tile ); } lock.unlock(); backlog.clear(); gl.Finish(); // signal to the master that the raytracing // of the current face has finished common.thread_ready.Signal(); if(common.Done()) break; // wait for the master to save the face image common.master_ready.Wait(); } }
void ChatWindow::setLogfileName(const QString& name) { // Only change name of logfile if the window was new. if(firstLog) { if (getTextView()) getTextView()->setContextMenuOptions(IrcContextMenus::ShowLogAction, true); // status panels get special treatment here, since they have no server at the beginning if (getType() == Status || getType() == DccChat) { logName = name + ".log"; } else if (m_server) { // make sure that no path delimiters are in the name logName = QString(m_server->getDisplayName().toLower()).append('_').append(name).append(".log").replace('/','_'); } // load backlog to show if(Preferences::self()->showBacklog()) { // "cd" into log path or create path, if it's not there cdIntoLogPath(); // Show last log lines. This idea was stole ... um ... inspired by PMP :) // Don't do this for the server status windows, though if((getType() != Status) && logfile.open(QIODevice::ReadOnly)) { qint64 filePosition; QString backlogLine; QTextStream backlog(&logfile); backlog.setCodec(QTextCodec::codecForName("UTF-8")); backlog.setAutoDetectUnicode(true); QStringList firstColumns; QStringList messages; int offset = 0; qint64 lastPacketHeadPosition = backlog.device()->size(); const unsigned int packetSize = 4096; while(messages.count() < Preferences::self()->backlogLines() && backlog.device()->size() > packetSize * offset) { QStringList firstColumnsInPacket; QStringList messagesInPacket; // packetSize * offset < size <= packetSize * ( offset + 1 ) // Check if the log is bigger than packetSize * ( offset + 1 ) if(backlog.device()->size() > packetSize * ( offset + 1 )) { // Set file pointer to the packet size above the offset backlog.seek(backlog.device()->size() - packetSize * ( offset + 1 )); // Skip first line, since it may be incomplete backlog.readLine(); } else { // Set file pointer to the head // Qt 4.5 Doc: Note that when using a QTextStream on a // QFile, calling reset() on the QFile will not have the // expected result because QTextStream buffers the file. // Use the QTextStream::seek() function instead. // backlog.device()->reset(); backlog.seek( 0 ); } // remember actual file position to check for deadlocks filePosition = backlog.pos(); qint64 currentPacketHeadPosition = filePosition; // Loop until end of file reached while(!backlog.atEnd() && filePosition < lastPacketHeadPosition) { backlogLine = backlog.readLine(); // check for deadlocks if(backlog.pos() == filePosition) { backlog.seek(filePosition + 1); } // if a tab character is present in the line, meaning it is a valid chatline if (backlogLine.contains('\t')) { // extract first column from log QString backlogFirst = backlogLine.left(backlogLine.indexOf('\t')); // cut first column from line backlogLine = backlogLine.mid(backlogLine.indexOf('\t') + 1); // Logfile is in utf8 so we don't need to do encoding stuff here // append backlog with time and first column to text view firstColumnsInPacket << backlogFirst; messagesInPacket << backlogLine; } // remember actual file position to check for deadlocks filePosition = backlog.pos(); } // while // remember the position not to read the same lines again lastPacketHeadPosition = currentPacketHeadPosition; ++offset; firstColumns = firstColumnsInPacket + firstColumns; messages = messagesInPacket + messages; } backlog.setDevice(0); logfile.close(); // trim int surplus = messages.count() - Preferences::self()->backlogLines(); // "surplus" can be a minus value. (when the backlog is too short) if(surplus > 0) { for(int i = 0 ; i < surplus ; ++i) { firstColumns.pop_front(); messages.pop_front(); } } QStringList::Iterator itFirstColumn = firstColumns.begin(); QStringList::Iterator itMessage = messages.begin(); for( ; itFirstColumn != firstColumns.end() ; ++itFirstColumn, ++itMessage ) appendBacklogMessage(*itFirstColumn, *itMessage); } } // if(Preferences::showBacklog()) } }