Download::Download(UserConnection& conn, QueueItem& qi, const string& path, bool supportsTrees) throw() : Transfer(conn, path, qi.getTTH()), tempTarget(qi.getTempTarget()), file(0), treeValid(false) { conn.setDownload(this); if(qi.isSet(QueueItem::FLAG_PARTIAL_LIST)) { setType(TYPE_PARTIAL_LIST); } else if(qi.isSet(QueueItem::FLAG_USER_LIST)) { setType(TYPE_FULL_LIST); } if(qi.getSize() != -1) { if(HashManager::getInstance()->getTree(getTTH(), getTigerTree())) { setTreeValid(true); setSegment(qi.getNextSegment(getTigerTree().getBlockSize(), conn.getChunkSize())); } else if(supportsTrees && !qi.getSource(conn.getUser())->isSet(QueueItem::Source::FLAG_NO_TREE) && qi.getSize() > HashManager::MIN_BLOCK_SIZE) { // Get the tree unless the file is small (for small files, we'd probably only get the root anyway) setType(TYPE_TREE); getTigerTree().setFileSize(qi.getSize()); setSegment(Segment(0, -1)); } else { // Use the root as tree to get some sort of validation at least... getTigerTree() = TigerTree(qi.getSize(), qi.getSize(), getTTH()); setTreeValid(true); setSegment(qi.getNextSegment(getTigerTree().getBlockSize(), 0)); } } }
void Amor::slotBubbleTimeout() { // has the queue item been displayed for long enough? QueueItem *first = mTipsQueue.head(); if( first->time() > BUBBLE_TIME_STEP && mBubble->isVisible() ) { first->setTime( first->time() - BUBBLE_TIME_STEP ); mBubbleTimer->setSingleShot( true ); mBubbleTimer->start( BUBBLE_TIME_STEP ); return; } // do not do anything if the mouse pointer is in the bubble if( mBubble->mouseWithin() ) { first->setTime( 500 ); // show this item for another 500ms mBubbleTimer->setSingleShot( true ); mBubbleTimer->start( BUBBLE_TIME_STEP ); return; } // are there any other tips pending? if( mTipsQueue.count() > 1 ) { mTipsQueue.dequeue(); showBubble(); // shows the next item in the queue } else { hideBubble( true ); // hideBubble calls dequeue() for itself. } }
void QueueDialog::btnMoveTop_clicked() { QueueItem* current = (QueueItem*) getCurrentList()->selectedItem(); if(current == 0) return; if(current->getPriority() == 0) return; QueueItem* previous = (QueueItem*) current->itemAbove(); if(previous == 0) return; int p = previous->getPriority(); while(previous != 0) { p = previous->getPriority(); previous->setPriority(p - 1); previous = (QueueItem*) previous->itemAbove(); } current->setPriority(p); getCurrentList()->sort(); }
void QueueDialog::btnDequeue_clicked() { QueueItem* current = (QueueItem*) getCurrentList()->selectedItem(); if(current == 0) return; if(current->getPriority() == 0) return; current->setPriority(0); getCurrentList()->sort(); }
void MainWindow::processQueue() { if(ui->listWidget_queue->count() == 0) return; if(!(ui->checkBox_queue_generateNormal->isChecked() || ui->checkBox_queue_generateSpec->isChecked() || ui->checkBox_queue_generateDisplace->isChecked())) { QMessageBox::information(this, "Nothing to do", "Select at least one map type to generate from the \"Save\" section"); return; } if(!exportPath.isValid()) { QMessageBox::information(this, "Invalid Export Path", "Export path is invalid!"); return; } //enable stop button ui->pushButton_stopProcessingQueue->setEnabled(true); //show progress bar and adjust maximum to queue size ui->progressBar_Queue->show(); ui->progressBar_Queue->setMaximum(ui->listWidget_queue->count()); for(int i = 0; i < ui->listWidget_queue->count() && !stopQueue; i++) { QueueItem *item = (QueueItem*)(ui->listWidget_queue->item(i)); //display status ui->statusBar->showMessage("Processing Image \"" + item->text() + "\""); ui->progressBar_Queue->setValue(i + 1); ui->listWidget_queue->item(i)->setSelected(true); //load image load(item->getUrl()); //save maps QUrl exportUrl = QUrl::fromLocalFile(exportPath.toLocalFile() + "/" + item->text()); std::cout << "[Queue] Image " << i + 1 << " exported: " << exportUrl.toLocalFile().toStdString() << std::endl; save(exportUrl); //user interface should stay responsive QCoreApplication::processEvents(); } //disable stop button ui->pushButton_stopProcessingQueue->setEnabled(false); stopQueue = false; //hide queue progress bar ui->progressBar_Queue->hide(); //enable "Open Export Folder" gui button ui->pushButton_openExportFolder->setEnabled(true); }
int QueueItem::compare(QListViewItem *i, int , bool ) const { QueueItem* it = (QueueItem*) i; if(it->getPriority() == torrentPriority) { const TorrentInterface* ti = it->getTC(); QString name1 = tc->getStats().torrent_name; QString name2 = ti->getStats().torrent_name; return name1.compare(name2); } return it->getPriority() < torrentPriority ? -1 : 1; }
void InvokeQueue::runQueue() { _isQueued.reset(); while (1) { QueueItem item; { LockerCS lock(_cs); if (_queue.empty()) break; item = _queue.front(); _queue.pop(); } item.func((ULONG_PTR)item.param); } }
void QueueScriptCoordinator::CheckQueue() { DownloadQueue* pDownloadQueue = DownloadQueue::Lock(); m_mutexQueue.Lock(); delete m_pCurItem; m_pCurItem = NULL; NZBInfo* pCurNZBInfo = NULL; Queue::iterator itCurItem = m_Queue.end(); for (Queue::iterator it = m_Queue.begin(); it != m_Queue.end(); ) { QueueItem* pQueueItem = *it; NZBInfo* pNZBInfo = pDownloadQueue->GetQueue()->Find(pQueueItem->GetNZBID()); // in a case this nzb must not be processed further - delete queue script from queue if (!pNZBInfo || pNZBInfo->GetDeleteStatus() != NZBInfo::dsNone || pNZBInfo->GetMarkStatus() == NZBInfo::ksBad) { delete pQueueItem; it = m_Queue.erase(it); continue; } if (!m_pCurItem || pQueueItem->GetEvent() > m_pCurItem->GetEvent()) { m_pCurItem = pQueueItem; itCurItem = it; pCurNZBInfo = pNZBInfo; } it++; } if (m_pCurItem) { m_Queue.erase(itCurItem); StartScript(pCurNZBInfo, m_pCurItem); } m_mutexQueue.Unlock(); DownloadQueue::Unlock(); }
bool QueueScriptCoordinator::HasJob(int iNZBID) { m_mutexQueue.Lock(); bool bWorking = m_pCurItem && m_pCurItem->GetNZBID() == iNZBID; if (!bWorking) { for (Queue::iterator it = m_Queue.begin(); it != m_Queue.end(); it++) { QueueItem* pQueueItem = *it; bWorking = pQueueItem->GetNZBID() == iNZBID; if (bWorking) { break; } } } m_mutexQueue.Unlock(); return bWorking; }
static gpointer worker_thread(gpointer data) { dbg(2, "new file load thread."); WfWorker* w = data; g_return_val_if_fail(w->msg_queue, NULL); g_async_queue_ref(w->msg_queue); // check for new work while(true){ QueueItem* job = g_async_queue_pop(w->msg_queue); // blocking dbg(2, "starting new job: %p", job); Waveform* waveform = g_weak_ref_get(&job->ref); if(waveform){ if(!job->cancelled){ // note that the job is run directly so that it runs in the worker thread. job->work(waveform, job->user_data); } g_idle_add(worker_unref_waveform, waveform); } g_timeout_add(1, worker_post, WF_NEW(WorkerJob, .job = job, .worker = w ) ); g_usleep(100); } return NULL; }
/* * Do clean-up and notifications in the main thread */ static bool worker_post(gpointer _wj) { WorkerJob* wj = _wj; QueueItem* job = wj->job; WfWorker* w = wj->worker; if(!job->cancelled){ Waveform* waveform = g_weak_ref_get(&job->ref); call(job->done, waveform, NULL, job->user_data); if(waveform) g_object_unref(waveform); } if(job->free && job->user_data){ job->free(job->user_data); job->user_data = NULL; } w->jobs = g_list_remove(w->jobs, job); g_weak_ref_set(&job->ref, NULL); g_free(job); g_free(wj); return G_SOURCE_REMOVE; }
void QueueDialog::writeQueue() { downloadList->sort(); seedList->sort(); int p = 0; QueueItem* item = (QueueItem*) downloadList->lastItem(); if(item != 0) { while(item != 0) { if(item->getPriority() != 0) item->setTorrentPriority(++p); else item->setTorrentPriority(0); item = (QueueItem*) item->itemAbove(); } } item = (QueueItem*) seedList->lastItem(); if(item == 0) { qman->orderQueue(); return; } p = 0; while(item != 0) { if(item->getPriority() != 0) item->setTorrentPriority(++p); else item->setTorrentPriority(0); item = (QueueItem*) item->itemAbove(); } qman->orderQueue(); }
void QueueDialog::btnMoveUp_clicked() { QueueItem* current = (QueueItem*) getCurrentList()->selectedItem(); if(current == 0) return; if(current->getPriority() == 0) return; QueueItem* previous = (QueueItem*) current->itemAbove(); if(previous == 0) return; else { int tmp = previous->getPriority(); previous->setPriority(current->getPriority()); current->setPriority(tmp); getCurrentList()->sort(); } }
void QueueDialog::enqueue(QueueItem* curr) { QueueItem* current = curr == 0 ? (QueueItem*) getCurrentList()->selectedItem() : curr; if(current == 0) return; if(current->getPriority() != 0) return; QueueItem* item = (QueueItem*) getCurrentList()->firstChild(); if(item == 0) return; while(item != 0) { if(item->getPriority() != 0) item->setPriority(item->getPriority() + 1); item = (QueueItem*) item->itemBelow(); } current->setPriority(1); getCurrentList()->sort(); }
Eloquent::QueueItem::QueueItem( const QueueItem& rhs ) : m_Data( rhs.Data() ) , m_Origin( rhs.Origin() ) , m_Destination( rhs.Destination() ) {}
Download::Download(UserConnection& conn, QueueItem& qi) noexcept : Transfer(conn, qi.getTarget(), qi.getTTH()), tempTarget(qi.getTempTarget()) { conn.setDownload(this); QueueItem::SourceConstIter source = qi.getSource(getUser()); if(qi.isSet(QueueItem::FLAG_PARTIAL_LIST)) { setType(TYPE_PARTIAL_LIST); } else if(qi.isSet(QueueItem::FLAG_USER_LIST)) { setType(TYPE_FULL_LIST); } if(source->isSet(QueueItem::Source::FLAG_PARTIAL)) setFlag(FLAG_PARTIAL); if(qi.isSet(QueueItem::FLAG_CLIENT_VIEW)) setFlag(FLAG_VIEW); if(qi.isSet(QueueItem::FLAG_MATCH_QUEUE)) setFlag(FLAG_QUEUE); if(qi.isSet(QueueItem::FLAG_VIEW_NFO)) setFlag(FLAG_NFO); if(qi.isSet(QueueItem::FLAG_RECURSIVE_LIST)) setFlag(FLAG_RECURSIVE); if(qi.isSet(QueueItem::FLAG_TTHLIST_BUNDLE)) setFlag(FLAG_TTHLIST_BUNDLE); if (qi.getPriority() == QueueItemBase::HIGHEST) setFlag(FLAG_HIGHEST_PRIO); if (qi.getBundle()) { dcassert(!qi.isSet(QueueItem::FLAG_USER_LIST)); dcassert(!qi.isSet(QueueItem::FLAG_TEXT)); setBundle(qi.getBundle()); } if(getType() == TYPE_FILE && qi.getSize() != -1) { if(HashManager::getInstance()->getTree(getTTH(), getTigerTree())) { setTreeValid(true); setSegment(qi.getNextSegment(getTigerTree().getBlockSize(), conn.getChunkSize(), conn.getSpeed(), source->getPartialSource(), true)); qi.setBlockSize(getTigerTree().getBlockSize()); } else if(conn.isSet(UserConnection::FLAG_SUPPORTS_TTHL) && !source->isSet(QueueItem::Source::FLAG_NO_TREE) && qi.getSize() > HashManager::MIN_BLOCK_SIZE) { // Get the tree unless the file is small (for small files, we'd probably only get the root anyway) setType(TYPE_TREE); getTigerTree().setFileSize(qi.getSize()); setSegment(Segment(0, -1)); } else { // Use the root as tree to get some sort of validation at least... getTigerTree() = TigerTree(qi.getSize(), qi.getSize(), getTTH()); setTreeValid(true); setSegment(qi.getNextSegment(getTigerTree().getBlockSize(), 0, 0, source->getPartialSource(), true)); } if ((getStartPos() + getSegmentSize()) != qi.getSize() || (conn.getDownload() && conn.getDownload()->isSet(FLAG_CHUNKED))) { setFlag(FLAG_CHUNKED); } if(getSegment().getOverlapped()) { setFlag(FLAG_OVERLAP); // set overlapped flag to original segment for(auto d: qi.getDownloads()) { if(d->getSegment().contains(getSegment())) { d->setOverlapped(true); break; } } } } }
Download::Download(UserConnection& conn, QueueItem& qi, const string& path, bool supportsTrees) noexcept : Transfer(conn, path, qi.getTTH()), tempTarget(qi.getTempTarget()), file(0), treeValid(false) { conn.setDownload(this); QueueItem::SourceConstIter source = qi.getSource(getUser()); if(qi.isSet(QueueItem::FLAG_PARTIAL_LIST)) { setType(TYPE_PARTIAL_LIST); } else if(qi.isSet(QueueItem::FLAG_USER_LIST)) { setType(TYPE_FULL_LIST); } if(getType() == TYPE_FILE && qi.getSize() != -1) { if(HashManager::getInstance()->getTree(getTTH(), getTigerTree())) { setTreeValid(true); setSegment(qi.getNextSegment(getTigerTree().getBlockSize(), conn.getChunkSize(),conn.getSpeed(), source->getPartialSource())); } else if(supportsTrees && conn.isSet(UserConnection::FLAG_SUPPORTS_TTHL) && !qi.getSource(conn.getUser())->isSet(QueueItem::Source::FLAG_NO_TREE) && qi.getSize() > HashManager::MIN_BLOCK_SIZE) { // Get the tree unless the file is small (for small files, we'd probably only get the root anyway) setType(TYPE_TREE); getTigerTree().setFileSize(qi.getSize()); setSegment(Segment(0, -1)); } else { // Use the root as tree to get some sort of validation at least... getTigerTree() = TigerTree(qi.getSize(), qi.getSize(), getTTH()); setTreeValid(true); setSegment(qi.getNextSegment(getTigerTree().getBlockSize(), 0, 0, source->getPartialSource())); } if(getSegment().getOverlapped()) { setFlag(FLAG_OVERLAP); // set overlapped flag to original segment for(DownloadList::const_iterator i = qi.getDownloads().begin(); i != qi.getDownloads().end(); ++i) { if((*i)->getSegment().contains(getSegment())) { (*i)->setOverlapped(true); break; } } } } }
void QueueScriptCoordinator::EnqueueScript(NZBInfo* pNZBInfo, EEvent eEvent) { if (!m_bHasQueueScripts) { return; } m_mutexQueue.Lock(); if (eEvent == qeNzbDownloaded) { // delete all other queued scripts for this nzb for (Queue::iterator it = m_Queue.begin(); it != m_Queue.end(); ) { QueueItem* pQueueItem = *it; if (pQueueItem->GetNZBID() == pNZBInfo->GetID()) { delete pQueueItem; it = m_Queue.erase(it); continue; } it++; } } // respect option "EventInterval" time_t tCurTime = time(NULL); if (eEvent == qeFileDownloaded && (g_pOptions->GetEventInterval() == -1 || (g_pOptions->GetEventInterval() > 0 && tCurTime - pNZBInfo->GetQueueScriptTime() > 0 && (int)(tCurTime - pNZBInfo->GetQueueScriptTime()) < g_pOptions->GetEventInterval()))) { m_mutexQueue.Unlock(); return; } for (ScriptConfig::Scripts::iterator it = g_pScriptConfig->GetScripts()->begin(); it != g_pScriptConfig->GetScripts()->end(); it++) { ScriptConfig::Script* pScript = *it; if (!pScript->GetQueueScript()) { continue; } bool bUseScript = false; // check queue-scripts const char* szQueueScript = g_pOptions->GetQueueScript(); if (!Util::EmptyStr(szQueueScript)) { // split szQueueScript into tokens Tokenizer tok(szQueueScript, ",;"); while (const char* szScriptName = tok.Next()) { if (Util::SameFilename(szScriptName, pScript->GetName())) { bUseScript = true; break; } } } // check post-processing-scripts if (!bUseScript) { for (NZBParameterList::iterator it = pNZBInfo->GetParameters()->begin(); it != pNZBInfo->GetParameters()->end(); it++) { NZBParameter* pParameter = *it; const char* szVarname = pParameter->GetName(); if (strlen(szVarname) > 0 && szVarname[0] != '*' && szVarname[strlen(szVarname)-1] == ':' && (!strcasecmp(pParameter->GetValue(), "yes") || !strcasecmp(pParameter->GetValue(), "on") || !strcasecmp(pParameter->GetValue(), "1"))) { char szScriptName[1024]; strncpy(szScriptName, szVarname, 1024); szScriptName[1024-1] = '\0'; szScriptName[strlen(szScriptName)-1] = '\0'; // remove trailing ':' if (Util::SameFilename(szScriptName, pScript->GetName())) { bUseScript = true; break; } } } } bUseScript &= Util::EmptyStr(pScript->GetQueueEvents()) || strstr(pScript->GetQueueEvents(), QUEUE_EVENT_NAMES[eEvent]); if (bUseScript) { bool bAlreadyQueued = false; if (eEvent == qeFileDownloaded) { // check if this script is already queued for this nzb for (Queue::iterator it2 = m_Queue.begin(); it2 != m_Queue.end(); it2++) { QueueItem* pQueueItem = *it2; if (pQueueItem->GetNZBID() == pNZBInfo->GetID() && pQueueItem->GetScript() == pScript) { bAlreadyQueued = true; break; } } } if (!bAlreadyQueued) { QueueItem* pQueueItem = new QueueItem(pNZBInfo->GetID(), pScript, eEvent); if (m_pCurItem) { m_Queue.push_back(pQueueItem); } else { StartScript(pNZBInfo, pQueueItem); } } pNZBInfo->SetQueueScriptTime(time(NULL)); } } m_mutexQueue.Unlock(); }
void SourceDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const { if ( option.rect.height() == 0 ) return; QStyleOptionViewItemV4 optIndentation = option; QStyleOptionViewItemV4 opt = option; painter->save(); painter->setRenderHint( QPainter::TextAntialiasing ); painter->setRenderHint( QPainter::SmoothPixmapTransform ); const bool selected = ( option.state & QStyle::State_Selected ) == QStyle::State_Selected; if ( selected ) painter->setOpacity( 1.0 ); else painter->setOpacity( 0.7 ); SourcesModel::RowType type = static_cast< SourcesModel::RowType >( index.data( SourcesModel::SourceTreeItemTypeRole ).toInt() ); SourceTreeItem* item = index.data( SourcesModel::SourceTreeItemRole ).value< SourceTreeItem* >(); Q_ASSERT( item ); initStyleOption( &opt, index ); opt.icon = QIcon(); opt.text.clear(); // shrink the indentations { int indentMult = 0; QModelIndex counter = index; while ( counter.parent().isValid() ) { indentMult++; counter = counter.parent(); } const int indentDelta = optIndentation.rect.x() - m_parent->viewport()->x(); optIndentation.rect.setX( optIndentation.rect.x() - indentDelta + indentMult * TomahawkUtils::DpiScaler::scaledY( m_parent, TREEVIEW_INDENT_ADD ) ); opt.rect.setX( 0 ); } if ( type == SourcesModel::Source || type == SourcesModel::ScriptCollection ) { paintSource( painter, optIndentation, index ); } else if ( type == SourcesModel::Group ) { paintGroup( painter, opt, index ); } else if ( type == SourcesModel::Category ) { paintCategory( painter, optIndentation, index ); } else if ( type == SourcesModel::Divider ) { const QRect middle = optIndentation.rect.adjusted( 0, m_margin / 16, 0, -m_margin / 16 ); const QColor bgcolor = opt.palette.color( QPalette::Base ); painter->setPen( bgcolor.darker( 120 ) ); painter->drawLine( middle.topLeft(), middle.topRight() ); painter->setPen( bgcolor.lighter( 120 ) ); painter->drawLine( middle.bottomLeft(), middle.bottomRight() ); } else { optIndentation.state &= ~QStyle::State_MouseOver; if ( !index.parent().parent().isValid() ) optIndentation.rect.adjust( m_margin / 4, 0, 0, 0 ); if ( type == SourcesModel::Inbox || type == SourcesModel::Queue || type == SourcesModel::Collection ) { QString count; if ( type == SourcesModel::Inbox ) { InboxItem* ii = qobject_cast< InboxItem* >( item ); if ( ii && ii->unlistenedCount() ) count = QString::number( ii->unlistenedCount() ); } else if ( type == SourcesModel::Queue ) { QueueItem* qi = qobject_cast< QueueItem* >( item ); if ( qi && qi->unlistenedCount() ) count = QString::number( qi->unlistenedCount() ); } else if ( type == SourcesModel::Collection ) { CollectionItem* ci = qobject_cast< CollectionItem* >( item ); if ( ci ) count = QString::number( ci->trackCount() ); } paintStandardItem( painter, optIndentation, index, count ); } else if ( type == SourcesModel::TemporaryPage || type == SourcesModel::DeletablePage || type == SourcesModel::RemovablePage ) { if ( opt.state & QStyle::State_MouseOver ) { m_iconHeight = ( opt.rect.height() / 2 ); paintStandardItem( painter, optIndentation, index ); // draw close icon const QRect r( opt.rect.right() - m_margin / 8 - m_iconHeight, opt.rect.y() + ( opt.rect.height() - m_iconHeight ) / 2, m_iconHeight, m_iconHeight ); painter->drawPixmap( r, TomahawkUtils::defaultPixmap( TomahawkUtils::ListRemove, TomahawkUtils::Original, r.size() ) ); } else paintStandardItem( painter, optIndentation, index ); } else if ( type == SourcesModel::StaticPlaylist ) { paintStandardItem( painter, optIndentation, index ); PlaylistItem* plItem = qobject_cast< PlaylistItem* >( item ); if ( plItem->canSubscribe() && !plItem->subscribedIcon().isNull() ) { const int imgWidth = optIndentation.rect.height() / 2; const QPixmap icon = plItem->subscribedIcon().scaled( imgWidth, imgWidth, Qt::KeepAspectRatio, Qt::SmoothTransformation ); const QRect subRect( optIndentation.rect.right() - m_margin / 2 - imgWidth, optIndentation.rect.top() + ( optIndentation.rect.height() - imgWidth ) / 2, imgWidth, imgWidth ); painter->drawPixmap( subRect, icon ); } if ( plItem->collaborative() ) { const int imgWidth = optIndentation.rect.height() / 2; const QRect subRect( optIndentation.rect.left(), optIndentation.rect.top(), imgWidth, imgWidth ); painter->drawPixmap( subRect, TomahawkUtils::defaultPixmap( TomahawkUtils::GreenDot, TomahawkUtils::Original, subRect.size() ) ); } } else paintStandardItem( painter, optIndentation, index ); } paintDecorations( painter, opt, index ); painter->restore(); }
/* * recv_writer_queue - return the number of queued items */ static int recv_writer_queue(void) { PGconn *conn; List *queue; int ret; char *instid = NULL; bool connection_used = false; pthread_mutex_lock(&writer_queue_lock); queue = writer_queue; writer_queue = NIL; pthread_mutex_unlock(&writer_queue_lock); if (list_length(queue) == 0) return 0; /* install writer schema */ if ((conn = writer_connect(superuser_connect)) == NULL) { elog(ERROR, "could not connect to repository"); /* discard current queue if can't connect to repository */ if (list_length(queue) > 0) { elog(WARNING, "writer discards %d items", list_length(queue)); list_destroy(queue, destroy_writer_queue); } return 0; } /* do the writer queue process */ if ((instid = get_instid(conn)) != NULL) { connection_used = true; while (list_length(queue) > 0) { QueueItem *item = (QueueItem *) linitial(queue); if (!item->exec(item, conn, instid)) { if (++item->retry < DB_MAX_RETRY) break; /* retry the item */ /* * discard if the retry count is exceeded to avoid infinite * loops at one bad item. */ elog(WARNING, "writer discard an item"); } item->free(item); queue = list_delete_first(queue); } } free(instid); /* delay on error */ if (list_length(queue) > 0) delay(); /* * When we have failed items, we concatenate to the head of writer queue * and retry them in the next cycle. */ pthread_mutex_lock(&writer_queue_lock); writer_queue = list_concat(queue, writer_queue); ret = list_length(writer_queue); pthread_mutex_unlock(&writer_queue_lock); /* update last used time of the connection. */ if (connection_used) writer_conn_last_used = time(NULL); return ret; }