コード例 #1
0
ファイル: publish.c プロジェクト: dazwiafl/transmission
void
tr_publisherFree( tr_publisher_t ** p )
{
    assert( p );
    assert( *p );

    tr_list_free( &( *p )->list, NULL );
    tr_free( *p );
    *p = NULL;
}
コード例 #2
0
ファイル: peer-io.c プロジェクト: miracle2k/transmission
static void
io_dtor( void * vio )
{
    tr_peerIo * io = vio;

    assert( tr_isPeerIo( io ) );
    assert( tr_amInEventThread( io->session ) );
    assert( io->session->events != NULL );

    dbgmsg( io, "in tr_peerIo destructor" );
    event_disable( io, EV_READ | EV_WRITE );
    tr_bandwidthDestruct( &io->bandwidth );
    evbuffer_free( io->outbuf );
    evbuffer_free( io->inbuf );
    tr_netClose( io->session, io->socket );
    tr_cryptoFree( io->crypto );
    tr_list_free( &io->outbuf_datatypes, tr_free );

    memset( io, ~0, sizeof( tr_peerIo ) );
    tr_free( io );
}
コード例 #3
0
ファイル: session.c プロジェクト: liesen/transmission-horn
static void
tr_closeAllConnections( void * vsession )
{
    tr_session *  session = vsession;
    tr_torrent *  tor;
    int           i, n;
    tr_torrent ** torrents;

    assert( tr_isSession( session ) );

    tr_statsClose( session );
    tr_sharedShuttingDown( session->shared );
    tr_rpcClose( &session->rpcServer );

    /* close the torrents.  get the most active ones first so that
     * if we can't get them all closed in a reasonable amount of time,
     * at least we get the most important ones first. */
    tor = NULL;
    n = session->torrentCount;
    torrents = tr_new( tr_torrent *, session->torrentCount );
    for( i = 0; i < n; ++i )
        torrents[i] = tor = tr_torrentNext( session, tor );
    qsort( torrents, n, sizeof( tr_torrent* ), compareTorrentByCur );
    for( i = 0; i < n; ++i )
        tr_torrentFree( torrents[i] );
    tr_free( torrents );

    tr_peerMgrFree( session->peerMgr );

    tr_trackerSessionClose( session );
    tr_list_free( &session->blocklists,
                  (TrListForeachFunc)_tr_blocklistFree );
    tr_webClose( &session->web );

    session->isClosed = TRUE;
}
コード例 #4
0
ファイル: web.c プロジェクト: RodrigoFerreira001/transmission
static void
tr_webThreadFunc (void * vsession)
{
  char * str;
  CURLM * multi;
  struct tr_web * web;
  int taskCount = 0;
  struct tr_web_task * task;
  tr_session * session = vsession;

  /* try to enable ssl for https support; but if that fails,
   * try a plain vanilla init */
  if (curl_global_init (CURL_GLOBAL_SSL))
    curl_global_init (0);

  web = tr_new0 (struct tr_web, 1);
  web->close_mode = ~0;
  web->taskLock = tr_lockNew ();
  web->tasks = NULL;
  web->curl_verbose = getenv ("TR_CURL_VERBOSE") != NULL;
  web->curl_ssl_verify = getenv ("TR_CURL_SSL_VERIFY") != NULL;
  web->curl_ca_bundle = getenv ("CURL_CA_BUNDLE");
  if (web->curl_ssl_verify)
    {
      tr_logAddNamedInfo ("web", "will verify tracker certs using envvar CURL_CA_BUNDLE: %s",
               web->curl_ca_bundle == NULL ? "none" : web->curl_ca_bundle);
      tr_logAddNamedInfo ("web", "NB: this only works if you built against libcurl with openssl or gnutls, NOT nss");
      tr_logAddNamedInfo ("web", "NB: invalid certs will show up as 'Could not connect to tracker' like many other errors");
    }

  str = tr_buildPath (session->configDir, "cookies.txt", NULL);
  if (tr_fileExists (str, NULL))
    web->cookie_filename = tr_strdup (str);
  tr_free (str);

  multi = curl_multi_init ();
  session->web = web;

  for (;;)
    {
      long msec;
      int unused;
      CURLMsg * msg;
      CURLMcode mcode;

      if (web->close_mode == TR_WEB_CLOSE_NOW)
        break;
      if ((web->close_mode == TR_WEB_CLOSE_WHEN_IDLE) && (web->tasks == NULL))
        break;

      /* add tasks from the queue */
      tr_lockLock (web->taskLock);
      while (web->tasks != NULL)
        {
          /* pop the task */
          task = web->tasks;
          web->tasks = task->next;
          task->next = NULL;

          dbgmsg ("adding task to curl: [%s]", task->url);
          curl_multi_add_handle (multi, createEasy (session, web, task));
          /*fprintf (stderr, "adding a task.. taskCount is now %d\n", taskCount);*/
          ++taskCount;
        }
      tr_lockUnlock (web->taskLock);

      /* unpause any paused curl handles */
      if (paused_easy_handles != NULL)
        {
          CURL * handle;
          tr_list * tmp;

          /* swap paused_easy_handles to prevent oscillation
             between writeFunc this while loop */
          tmp = paused_easy_handles;
          paused_easy_handles = NULL;

          while ((handle = tr_list_pop_front (&tmp)))
            curl_easy_pause (handle, CURLPAUSE_CONT);
        }

      /* maybe wait a little while before calling curl_multi_perform () */
      msec = 0;
      curl_multi_timeout (multi, &msec);
      if (msec < 0)
        msec = THREADFUNC_MAX_SLEEP_MSEC;
      if (session->isClosed)
        msec = 100; /* on shutdown, call perform () more frequently */
      if (msec > 0)
        {
          int usec;
          int max_fd;
          struct timeval t;
          fd_set r_fd_set, w_fd_set, c_fd_set;

          max_fd = 0;
          FD_ZERO (&r_fd_set);
          FD_ZERO (&w_fd_set);
          FD_ZERO (&c_fd_set);
          curl_multi_fdset (multi, &r_fd_set, &w_fd_set, &c_fd_set, &max_fd);

          if (msec > THREADFUNC_MAX_SLEEP_MSEC)
            msec = THREADFUNC_MAX_SLEEP_MSEC;

          usec = msec * 1000;
          t.tv_sec =  usec / 1000000;
          t.tv_usec = usec % 1000000;
          tr_select (max_fd+1, &r_fd_set, &w_fd_set, &c_fd_set, &t);
        }

      /* call curl_multi_perform () */
      do
        mcode = curl_multi_perform (multi, &unused);
      while (mcode == CURLM_CALL_MULTI_PERFORM);

      /* pump completed tasks from the multi */
      while ((msg = curl_multi_info_read (multi, &unused)))
        {
          if ((msg->msg == CURLMSG_DONE) && (msg->easy_handle != NULL))
            {
              double total_time;
              struct tr_web_task * task;
              long req_bytes_sent;
              CURL * e = msg->easy_handle;
              curl_easy_getinfo (e, CURLINFO_PRIVATE, (void*)&task);
              assert (e == task->curl_easy);
              curl_easy_getinfo (e, CURLINFO_RESPONSE_CODE, &task->code);
              curl_easy_getinfo (e, CURLINFO_REQUEST_SIZE, &req_bytes_sent);
              curl_easy_getinfo (e, CURLINFO_TOTAL_TIME, &total_time);
              task->did_connect = task->code>0 || req_bytes_sent>0;
              task->did_timeout = !task->code && (total_time >= task->timeout_secs);
              curl_multi_remove_handle (multi, e);
              tr_list_remove_data (&paused_easy_handles, e);
              curl_easy_cleanup (e);
              tr_runInEventThread (task->session, task_finish_func, task);
              --taskCount;
            }
        }
    }

  /* Discard any remaining tasks.
   * This is rare, but can happen on shutdown with unresponsive trackers. */
  while (web->tasks != NULL)
    {
      task = web->tasks;
      web->tasks = task->next;
      dbgmsg ("Discarding task \"%s\"", task->url);
      task_free (task);
    }

  /* cleanup */
  tr_list_free (&paused_easy_handles, NULL);
  curl_multi_cleanup (multi);
  tr_lockFree (web->taskLock);
  tr_free (web->cookie_filename);
  tr_free (web);
  session->web = NULL;
}