~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/session.cc

Merging Eric's refactoring and cleanup of Listen and Protocol

Show diffs side-by-side

added added

removed removed

Lines of Context:
41
41
#include <algorithm>
42
42
 
43
43
using namespace std;
 
44
using namespace drizzled;
44
45
 
45
46
extern "C"
46
47
{
58
59
const char * const Session::DEFAULT_WHERE= "field list";
59
60
extern pthread_key_t THR_Session;
60
61
extern pthread_key_t THR_Mem_root;
 
62
extern uint32_t max_used_connections;
 
63
extern drizzled::atomic<uint32_t> connection_count;
61
64
 
62
65
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
63
66
/* Used templates */
168
171
  session->row_count++;
169
172
}
170
173
 
171
 
Session::Session(Protocol *protocol_arg)
 
174
Session::Session(plugin::Protocol *protocol_arg)
172
175
  :
173
176
  Statement(&main_lex, &main_mem_root, /* statement id */ 0),
174
177
  Open_tables_state(refresh_version),
 
178
  scheduler(NULL),
 
179
  scheduler_arg(NULL),
175
180
  lock_id(&main_lock_id),
176
181
  user_time(0),
177
182
  arg_of_last_insert_id_function(false),
188
193
  derived_tables_processing(false),
189
194
  tablespace_op(false),
190
195
  m_lip(NULL),
191
 
  scheduler(0),
192
196
  cached_table(0)
193
197
{
194
 
  uint64_t tmp;
195
 
 
196
198
  memset(process_list_info, 0, PROCESS_LIST_WIDTH);
197
199
 
198
200
  /*
224
226
  replication_data= 0;
225
227
  mysys_var= 0;
226
228
  dbug_sentry=Session_SENTRY_MAGIC;
227
 
  client_capabilities= 0;                       // minimalistic client
228
229
  cleanup_done= abort_on_warning= no_warnings_for_error= false;
229
230
  peer_port= 0;                                 // For SHOW PROCESSLIST
230
231
  transaction.on= 1;
265
266
            (hash_get_key) get_var_key,
266
267
            (hash_free_key) free_user_var, 0);
267
268
 
268
 
  /* Protocol */
269
269
  protocol= protocol_arg;
270
270
  protocol->setSession(this);
271
271
 
272
 
  const Query_id& local_query_id= Query_id::get_query_id();
273
 
  tmp= sql_rnd();
274
 
  protocol->setRandom(tmp + (uint64_t) &protocol,
275
 
                      tmp + (uint64_t)local_query_id.value());
276
272
  substitute_null_with_insert_id = false;
277
273
  thr_lock_info_init(&lock_info); /* safety: will be reset after start */
278
274
  thr_lock_owner_init(&main_lock_id, &lock_info);
356
352
}
357
353
#endif
358
354
 
359
 
/*
360
 
  Init Session for query processing.
361
 
  This has to be called once before we call mysql_parse.
362
 
  See also comments in session.h.
363
 
*/
364
 
 
365
 
void Session::init_for_queries()
366
 
{
367
 
  set_time();
368
 
  ha_enable_transaction(this,true);
369
 
 
370
 
  reset_root_defaults(mem_root, variables.query_alloc_block_size,
371
 
                      variables.query_prealloc_size);
372
 
  reset_root_defaults(&transaction.mem_root,
373
 
                      variables.trans_alloc_block_size,
374
 
                      variables.trans_prealloc_size);
375
 
  transaction.xid_state.xid.null();
376
 
  transaction.xid_state.in_session=1;
377
 
}
378
 
 
379
 
 
380
355
/* Do operations that may take a long time */
381
356
 
382
357
void Session::cleanup(void)
499
474
{
500
475
  Session_CHECK_SENTRY(this);
501
476
  safe_mutex_assert_owner(&LOCK_delete);
502
 
  Scheduler &thread_scheduler= get_thread_scheduler();
503
477
 
504
478
  killed= state_to_set;
505
479
  if (state_to_set != Session::KILL_QUERY)
506
480
  {
507
 
    thread_scheduler.post_kill_notification(this);
 
481
    scheduler->killSession(this);
508
482
  }
509
483
  if (mysys_var)
510
484
  {
542
516
  Remember the location of thread info, the structure needed for
543
517
  sql_alloc() and the structure for the net buffer
544
518
*/
545
 
bool Session::store_globals()
 
519
bool Session::storeGlobals()
546
520
{
547
521
  /*
548
522
    Assert that thread_stack is initialized: it's necessary to be able
552
526
 
553
527
  if (pthread_setspecific(THR_Session,  this) ||
554
528
      pthread_setspecific(THR_Mem_root, &mem_root))
555
 
    return 1;
 
529
    return true;
 
530
 
556
531
  mysys_var=my_thread_var;
557
532
 
558
533
  /*
567
542
    created in another thread
568
543
  */
569
544
  thr_lock_info_init(&lock_info);
570
 
  return 0;
 
545
  return false;
571
546
}
572
547
 
 
548
/*
 
549
  Init Session for query processing.
 
550
  This has to be called once before we call mysql_parse.
 
551
  See also comments in session.h.
 
552
*/
 
553
 
573
554
void Session::prepareForQueries()
574
555
{
575
556
  if (variables.max_join_size == HA_POS_ERROR)
576
557
    options |= OPTION_BIG_SELECTS;
577
 
  if (client_capabilities & CLIENT_COMPRESS)
578
 
  {
579
 
    protocol->enableCompression();
580
 
  }
581
558
 
582
559
  version= refresh_version;
583
560
  set_proc_info(NULL);
584
561
  command= COM_SLEEP;
585
562
  set_time();
586
 
  init_for_queries();
 
563
  ha_enable_transaction(this,true);
 
564
 
 
565
  reset_root_defaults(mem_root, variables.query_alloc_block_size,
 
566
                      variables.query_prealloc_size);
 
567
  reset_root_defaults(&transaction.mem_root,
 
568
                      variables.trans_alloc_block_size,
 
569
                      variables.trans_prealloc_size);
 
570
  transaction.xid_state.xid.null();
 
571
  transaction.xid_state.in_session=1;
587
572
}
588
573
 
589
574
bool Session::initGlobals()
590
575
{
591
 
  if (store_globals())
 
576
  if (storeGlobals())
592
577
  {
593
578
    disconnect(ER_OUT_OF_RESOURCES, true);
594
579
    statistic_increment(aborted_connects, &LOCK_status);
595
 
    Scheduler &thread_scheduler= get_thread_scheduler();
596
 
    thread_scheduler.end_thread(this, 0);
597
 
    return false;
598
 
  }
599
 
  return true;
 
580
    return true;
 
581
  }
 
582
  return false;
 
583
}
 
584
 
 
585
void Session::run()
 
586
{
 
587
  if (initGlobals() || authenticate())
 
588
  {
 
589
    disconnect(0, true);
 
590
    return;
 
591
  }
 
592
 
 
593
  prepareForQueries();
 
594
 
 
595
  while (! protocol->haveError() && killed != KILL_CONNECTION)
 
596
  {
 
597
    if (! executeStatement())
 
598
      break;
 
599
  }
 
600
 
 
601
  disconnect(0, true);
 
602
}
 
603
 
 
604
bool Session::schedule()
 
605
{
 
606
  scheduler= get_thread_scheduler();
 
607
 
 
608
  ++connection_count;
 
609
 
 
610
  if (connection_count > max_used_connections)
 
611
    max_used_connections= connection_count;
 
612
 
 
613
  thread_id= variables.pseudo_thread_id= global_thread_id++;
 
614
 
 
615
  pthread_mutex_lock(&LOCK_thread_count);
 
616
  session_list.push_back(this);
 
617
  pthread_mutex_unlock(&LOCK_thread_count);
 
618
 
 
619
  if (scheduler->addSession(this))
 
620
  {
 
621
    char error_message_buff[DRIZZLE_ERRMSG_SIZE];
 
622
 
 
623
    killed= Session::KILL_CONNECTION;
 
624
 
 
625
    statistic_increment(aborted_connects, &LOCK_status);
 
626
 
 
627
    /* Can't use my_error() since store_globals has not been called. */
 
628
    /* TODO replace will better error message */
 
629
    snprintf(error_message_buff, sizeof(error_message_buff),
 
630
             ER(ER_CANT_CREATE_THREAD), 1);
 
631
    protocol->sendError(ER_CANT_CREATE_THREAD, error_message_buff);
 
632
    return true;
 
633
  }
 
634
 
 
635
  return false;
600
636
}
601
637
 
602
638
bool Session::authenticate()
603
639
{
604
640
  lex_start(this);
605
641
  if (protocol->authenticate())
606
 
    return true;
 
642
    return false;
607
643
 
608
644
  statistic_increment(aborted_connects, &LOCK_status);
609
 
  return false;
 
645
  return true;
610
646
}
611
647
 
612
648
bool Session::checkUser(const char *passwd, uint32_t passwd_len, const char *in_db)
728
764
    my_error(ER_XAER_RMFAIL, MYF(0), xa_state_names[transaction.xid_state.xa_state]);
729
765
    return false;
730
766
  }
731
 
  switch (completion) 
 
767
  switch (completion)
732
768
  {
733
769
    case COMMIT:
734
770
      /*
970
1006
  }
971
1007
  item->maybe_null= 1;
972
1008
  field_list.push_back(new Item_empty_string("Extra", 255, cs));
973
 
  return (result->send_fields(field_list,
974
 
                              Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF));
 
1009
  return (result->send_fields(field_list));
975
1010
}
976
1011
 
977
1012
/************************************************************************