void
mongoc_client_pool_push (mongoc_client_pool_t *pool,
                         mongoc_client_t      *client)
{
   ENTRY;

   BSON_ASSERT (pool);
   BSON_ASSERT (client);

   mongoc_mutex_lock(&pool->mutex);
   if (pool->size > pool->min_pool_size) {
      mongoc_client_t *old_client;
      old_client = (mongoc_client_t *)_mongoc_queue_pop_head (&pool->queue);
      if (old_client) {
          mongoc_client_destroy (old_client);
          pool->size--;
      }
   }
   mongoc_mutex_unlock(&pool->mutex);

   mongoc_mutex_lock (&pool->mutex);
   _mongoc_queue_push_tail (&pool->queue, client);

   mongoc_cond_signal(&pool->cond);
   mongoc_mutex_unlock(&pool->mutex);

   EXIT;
}
void
mongoc_client_kill_cursor (mongoc_client_t *client,
                           int64_t          cursor_id)
{
   mongoc_topology_t *topology;
   mongoc_server_description_t *selected_server;
   mongoc_read_prefs_t *read_prefs;
   uint32_t server_id = 0;

   topology = client->topology;
   read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY);

   mongoc_mutex_lock (&topology->mutex);

   /* see if there's a known writable server - do no I/O or retries */
   selected_server = mongoc_topology_description_select(&topology->description,
                                                        MONGOC_SS_WRITE,
                                                        read_prefs,
                                                        15);

   if (selected_server) {
      server_id = selected_server->id;
   }

   mongoc_mutex_unlock (&topology->mutex);

   if (server_id) {
      _mongoc_client_kill_cursor (client, selected_server->id, cursor_id);
   } else {
      MONGOC_INFO ("No server available for mongoc_client_kill_cursor");
   }

   mongoc_read_prefs_destroy (read_prefs);
}
Example #3
0
mongoc_client_t *
mongoc_client_pool_try_pop (mongoc_client_pool_t *pool)
{
   mongoc_client_t *client;

   ENTRY;

   BSON_ASSERT (pool);

   mongoc_mutex_lock(&pool->mutex);

   if (!(client = (mongoc_client_t *)_mongoc_queue_pop_head(&pool->queue))) {
      if (pool->size < pool->max_pool_size) {
         client = _mongoc_client_new_from_uri(pool->uri, pool->topology);
#ifdef MONGOC_ENABLE_SSL
         if (pool->ssl_opts_set) {
            mongoc_client_set_ssl_opts (client, &pool->ssl_opts);
         }
#endif
         pool->size++;
      }
   }

   mongoc_mutex_unlock(&pool->mutex);

   RETURN(client);
}
Example #4
0
mongoc_client_t *
mongoc_client_pool_pop (mongoc_client_pool_t *pool)
{
   mongoc_client_t *client;

   ENTRY;

   BSON_ASSERT (pool);

   mongoc_mutex_lock(&pool->mutex);

again:
   if (!(client = (mongoc_client_t *)_mongoc_queue_pop_head(&pool->queue))) {
      if (pool->size < pool->max_pool_size) {
         client = _mongoc_client_new_from_uri(pool->uri, pool->topology);
         client->error_api_version = pool->error_api_version;
         _mongoc_client_set_apm_callbacks_private (client,
                                                   &pool->apm_callbacks,
                                                   pool->apm_context);
#ifdef MONGOC_ENABLE_SSL
         if (pool->ssl_opts_set) {
            mongoc_client_set_ssl_opts (client, &pool->ssl_opts);
         }
#endif
         pool->size++;
      } else {
         mongoc_cond_wait(&pool->cond, &pool->mutex);
         GOTO(again);
      }
   }

   mongoc_mutex_unlock(&pool->mutex);

   RETURN(client);
}
Example #5
0
void
mock_server_remove_autoresponder (mock_server_t *server,
                                  int id)
{
   size_t i;
   autoresponder_handle_t *handles;

   mongoc_mutex_lock (&server->mutex);
   handles = (autoresponder_handle_t *) server->autoresponders.data;
   for (i = 0; i < server->autoresponders.len; i++) {
      if (handles[i].id == id) {
         /* left-shift everyone after */
         server->autoresponders.len--;
         for (; i < server->autoresponders.len; i++) {
            handles[i] = handles[i + 1];
         }

         autoresponder_handle_destroy (handles);

         break;
      }
   }

   mongoc_mutex_unlock (&server->mutex);
}
Example #6
0
void
mock_server_set_verbose (mock_server_t *server, bool verbose)
{
   mongoc_mutex_lock (&server->mutex);
   server->verbose = verbose;
   mongoc_mutex_unlock (&server->mutex);
}
bool
mongoc_client_pool_set_metadata (mongoc_client_pool_t   *pool,
                                 const char             *driver_name,
                                 const char             *version,
                                 const char             *platform)
{
   bool ret = false;
   bson_t* metadata;

   mongoc_mutex_lock (&pool->mutex);

   if (pool->metadata_set) {
      goto done;
   }

   if (mongoc_topology_is_scanner_active (pool->topology)) {
      /* Once the scanner is active we cannot tell it to send
         different metadata */
      goto done;
   }

   metadata = &pool->topology->scanner->ismaster_metadata;
   ret = mongoc_client_metadata_set_data (metadata,
                                          driver_name,
                                          version,
                                          platform);

   if (ret) {
      pool->metadata_set = true;
   }
done:
   mongoc_mutex_unlock (&pool->mutex);

   return ret;
}
bool
mongoc_client_pool_set_application (mongoc_client_pool_t   *pool,
                                    const char             *application_name)
{
   bool ret;
   bson_t* metadata;
   /* Locking mutex even though this function can only get called once because
      we don't want to write to the metadata bson_t if someone else is reading
      from it at the same time */
   mongoc_mutex_lock (&pool->mutex);

   if (mongoc_topology_is_scanner_active (pool->topology)) {
      /* Once the scanner is active we cannot tell it to send
         different metadata */
      ret = false;
      goto done;
   }

   metadata = &pool->topology->scanner->ismaster_metadata;
   ret = mongoc_client_metadata_set_application (metadata, application_name);
done:
   mongoc_mutex_unlock (&pool->mutex);

   return ret;
}
void
mongoc_log (mongoc_log_level_t  log_level,
            const char         *log_domain,
            const char         *format,
            ...)
{
   va_list args;
   char *message;
   static mongoc_once_t once = MONGOC_ONCE_INIT;

   mongoc_once(&once, &_mongoc_ensure_mutex_once);

   if (!gLogFunc
#ifdef MONGOC_TRACE
         || (log_level == MONGOC_LOG_LEVEL_TRACE && !gLogTrace)
#endif
      ) {
      return;
   }

   BSON_ASSERT (format);

   va_start(args, format);
   message = bson_strdupv_printf(format, args);
   va_end(args);

   mongoc_mutex_lock(&gLogMutex);
   gLogFunc(log_level, log_domain, message, gLogData);
   mongoc_mutex_unlock(&gLogMutex);

   bson_free(message);
}
Example #10
0
void
mock_server_set_rand_delay (mock_server_t *server, bool rand_delay)
{
   mongoc_mutex_lock (&server->mutex);
   server->rand_delay = rand_delay;
   mongoc_mutex_unlock (&server->mutex);
}
Example #11
0
void
mongoc_log (mongoc_log_level_t log_level,
            const char *log_domain,
            const char *format,
            ...)
{
   va_list args;
   char *message;
   int stop_logging;

   mongoc_once (&once, &_mongoc_ensure_mutex_once);

   stop_logging = !gLogFunc;
#ifdef MONGOC_TRACE
   stop_logging =
      stop_logging || (log_level == MONGOC_LOG_LEVEL_TRACE && !gLogTrace);
#endif
   if (stop_logging) {
      return;
   }

   BSON_ASSERT (format);

   va_start (args, format);
   message = bson_strdupv_printf (format, args);
   va_end (args);

   mongoc_mutex_lock (&gLogMutex);
   gLogFunc (log_level, log_domain, message, gLogData);
   mongoc_mutex_unlock (&gLogMutex);

   bson_free (message);
}
static int
mongoc_sasl_mutex_lock (void *mutex)
{
   mongoc_mutex_lock ((mongoc_mutex_t *) mutex);

   return SASL_OK;
}
/** run as a child thread by test_mongoc_tls_hangup
 *
 * It:
 *    1. spins up
 *    2. waits on a condvar until the server is up
 *    3. connects to the server's port
 *    4. writes a byte
 *    5. confirms that the server hangs up promptly
 *    6. shuts down
 */
static void *
ssl_hangup_client (void *ptr)
{
   ssl_test_data_t *data = (ssl_test_data_t *)ptr;
   mongoc_stream_t *sock_stream;
   mongoc_stream_t *ssl_stream;
   mongoc_socket_t *conn_sock;
   char buf = 'b';
   ssize_t r;
   mongoc_iovec_t riov;
   mongoc_iovec_t wiov;
   struct sockaddr_in server_addr = { 0 };
   int64_t start_time;
   bson_error_t error;

   conn_sock = mongoc_socket_new (AF_INET, SOCK_STREAM, 0);
   assert (conn_sock);

   mongoc_mutex_lock (&data->cond_mutex);
   while (!data->server_port) {
      mongoc_cond_wait (&data->cond, &data->cond_mutex);
   }
   mongoc_mutex_unlock (&data->cond_mutex);

   server_addr.sin_family = AF_INET;
   server_addr.sin_port = htons (data->server_port);
   server_addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);

   r = mongoc_socket_connect (conn_sock, (struct sockaddr *)&server_addr,
                              sizeof (server_addr), -1);
   assert (r == 0);

   sock_stream = mongoc_stream_socket_new (conn_sock);
   assert (sock_stream);

   ssl_stream = mongoc_stream_tls_new (sock_stream, data->client, 1);
   assert (ssl_stream);

   r = mongoc_stream_tls_handshake_block (ssl_stream, data->host, TIMEOUT, &error);
   assert (r);

   wiov.iov_base = (void *)&buf;
   wiov.iov_len = 1;
   r = mongoc_stream_writev (ssl_stream, &wiov, 1, TIMEOUT);
   assert (r == 1);

   riov.iov_base = (void *)&buf;
   riov.iov_len = 1;

   /* we should notice promptly that the server hangs up */
   start_time = bson_get_monotonic_time ();
   r = mongoc_stream_readv (ssl_stream, &riov, 1, 1, TIMEOUT);
   /* time is in microseconds */
   assert (bson_get_monotonic_time () - start_time < 1000 * 1000);
   assert (r == -1);
   mongoc_stream_destroy (ssl_stream);
   data->client_result->result = SSL_TEST_SUCCESS;
   return NULL;
}
Example #14
0
void
mock_server_set_request_timeout_msec (mock_server_t *server,
                                      int64_t request_timeout_msec)
{
   mongoc_mutex_lock (&server->mutex);
   server->request_timeout_msec = request_timeout_msec;
   mongoc_mutex_unlock (&server->mutex);
}
Example #15
0
/*--------------------------------------------------------------------------
 *
 * mock_server_set_ssl_opts --
 *
 *       Set server-side SSL options before calling mock_server_run.
 *
 * Returns:
 *       None.
 *
 * Side effects:
 *       None.
 *
 *--------------------------------------------------------------------------
 */
void
mock_server_set_ssl_opts (mock_server_t *server,
                          mongoc_ssl_opt_t *opts)
{
   mongoc_mutex_lock (&server->mutex);
   server->ssl = true;
   memcpy (&server->ssl_opts, opts, sizeof *opts);
   mongoc_mutex_unlock (&server->mutex);
}
Example #16
0
void
mongoc_log_set_handler (mongoc_log_func_t log_func, void *user_data)
{
   mongoc_once (&once, &_mongoc_ensure_mutex_once);

   mongoc_mutex_lock (&gLogMutex);
   gLogFunc = log_func;
   gLogData = user_data;
   mongoc_mutex_unlock (&gLogMutex);
}
Example #17
0
double
mock_server_get_uptime_sec (mock_server_t *server)
{
   double uptime;

   mongoc_mutex_lock (&server->mutex);
   uptime = (bson_get_monotonic_time () - server->start_time) / 1e6;
   mongoc_mutex_unlock (&server->mutex);

   return uptime;
}
Example #18
0
sync_queue_t *
mock_server_get_queue (mock_server_t *server)
{
   sync_queue_t *q;

   mongoc_mutex_lock (&server->mutex);
   q = server->q;
   mongoc_mutex_unlock (&server->mutex);

   return q;
}
Example #19
0
bool
mock_server_get_rand_delay (mock_server_t *server)
{
   bool rand_delay;

   mongoc_mutex_lock (&server->mutex);
   rand_delay = server->rand_delay;
   mongoc_mutex_unlock (&server->mutex);

   return rand_delay;
}
Example #20
0
int64_t
mock_server_get_request_timeout_msec (mock_server_t *server)
{
   int64_t request_timeout_msec;

   mongoc_mutex_lock (&server->mutex);
   request_timeout_msec = server->request_timeout_msec;
   mongoc_mutex_unlock (&server->mutex);

   return request_timeout_msec;
}
Example #21
0
bool
mock_server_get_verbose (mock_server_t *server)
{
   bool verbose;

   mongoc_mutex_lock (&server->mutex);
   verbose = server->verbose;
   mongoc_mutex_unlock (&server->mutex);

   return verbose;
}
Example #22
0
void
future_resolve (future_t *future, future_value_t return_value)
{
   mongoc_mutex_lock (&future->mutex);
   assert (!future->resolved);
   assert (future->return_value.type == return_value.type);
   future->return_value = return_value;
   future->resolved = true;
   mongoc_cond_signal (&future->cond);
   mongoc_mutex_unlock (&future->mutex);
}
Example #23
0
const mongoc_uri_t *
mock_server_get_uri (mock_server_t *server)
{
   mongoc_uri_t *uri;

   mongoc_mutex_lock (&server->mutex);
   uri = server->uri;
   mongoc_mutex_unlock (&server->mutex);

   return uri;
}
Example #24
0
static bool
_mock_server_stopping (mock_server_t *server)
{
   bool stopped;

   mongoc_mutex_lock (&server->mutex);
   stopped = server->stopped;
   mongoc_mutex_unlock (&server->mutex);

   return stopped;
}
Example #25
0
void
mongoc_log_set_handler (mongoc_log_func_t  log_func,
                        void              *user_data)
{
   mongoc_once_t once = MONGOC_ONCE_INIT;
   mongoc_once(&once, &_mongoc_ensure_mutex_once);

   mongoc_mutex_lock(&gLogMutex);
   gLogFunc = log_func;
   mongoc_mutex_unlock(&gLogMutex);
}
Example #26
0
void
mock_server_run_in_thread (mock_server_t *server)
{
   BSON_ASSERT (server);

   server->using_main_thread = true;

   mongoc_mutex_lock (&server->mutex);
   mongoc_thread_create (&server->main_thread, main_thread, server);
   mongoc_cond_wait (&server->cond, &server->mutex);
   mongoc_mutex_unlock (&server->mutex);
}
Example #27
0
static void
_mongoc_ssl_thread_locking_callback (int         mode,
                                     int         type,
                                     const char *file,
                                     int         line)
{
   if (mode & CRYPTO_LOCK) {
      mongoc_mutex_lock (&gMongocSslThreadLocks[type]);
   } else {
      mongoc_mutex_unlock (&gMongocSslThreadLocks[type]);
   }
}
Example #28
0
void
mongoc_client_pool_min_size(mongoc_client_pool_t *pool,
                            uint32_t              min_pool_size)
{
   ENTRY;

   mongoc_mutex_lock (&pool->mutex);
   pool->min_pool_size = min_pool_size;
   mongoc_mutex_unlock (&pool->mutex);

   EXIT;
}
Example #29
0
/* TODO: merge with mock_server_reply? */
void
mock_server_reply_simple (mock_server_t *server,
                          mongoc_stream_t *client,
                          const mongoc_rpc_t *request,
                          mongoc_reply_flags_t flags,
                          const bson_t *doc,
                          int64_t cursor_id)
{
   mongoc_iovec_t *iov;
   mongoc_array_t ar;
   mongoc_rpc_t r = {{ 0 }};
   size_t expected = 0;
   ssize_t n_written;
   int iovcnt;
   int i;

   BSON_ASSERT (server);
   BSON_ASSERT (request);
   BSON_ASSERT (client);
   BSON_ASSERT (doc);

   _mongoc_array_init (&ar, sizeof (mongoc_iovec_t));

   mongoc_mutex_lock (&server->mutex);
   r.reply.request_id = ++server->last_response_id;
   mongoc_mutex_unlock (&server->mutex);
   r.reply.msg_len = 0;
   r.reply.response_to = request->header.request_id;
   r.reply.opcode = MONGOC_OPCODE_REPLY;
   r.reply.flags = flags;
   r.reply.cursor_id = cursor_id;
   r.reply.start_from = 0;
   r.reply.n_returned = 1;
   r.reply.documents = bson_get_data (doc);
   r.reply.documents_len = doc->len;

   _mongoc_rpc_gather (&r, &ar);
   _mongoc_rpc_swab_to_le (&r);

   iov = (mongoc_iovec_t *)ar.data;
   iovcnt = (int) ar.len;

   for (i = 0; i < iovcnt; i++) {
      expected += iov[i].iov_len;
   }

   n_written = mongoc_stream_writev (client, iov, (size_t) iovcnt, -1);

   assert (n_written == expected);

   _mongoc_array_destroy (&ar);
}
Example #30
0
size_t
mongoc_client_pool_get_size (mongoc_client_pool_t *pool)
{
   size_t size = 0;

   ENTRY;

   mongoc_mutex_lock (&pool->mutex);
   size = pool->size;
   mongoc_mutex_unlock (&pool->mutex);

   RETURN (size);
}