static int check_lock(struct st_lock_list *list, const char* lock_type,
                      const char *where, my_bool same_owner, my_bool no_cond)
{
  THR_LOCK_DATA *data,**prev;
  uint count=0;
  THR_LOCK_INFO *first_owner= NULL;

  prev= &list->data;
  if (list->data)
  {
    enum thr_lock_type last_lock_type=list->data->type;

    if (same_owner && list->data)
      first_owner= list->data->owner;
    for (data=list->data; data && count++ < MAX_LOCKS ; data=data->next)
    {
      if (data->type != last_lock_type)
        last_lock_type=TL_IGNORE;
      if (data->prev != prev)
      {
        my_message_stderr(0, "prev link %d didn't point at "
                          "previous lock at %s: %s", count, lock_type, where);
        return 1;
      }
      if (same_owner &&
          !thr_lock_owner_equal(data->owner, first_owner) &&
          last_lock_type != TL_WRITE_ALLOW_WRITE)
      {
        my_message_stderr(0, "Found locks from different threads "
                          "in %s: %s", lock_type, where);
        return 1;
      }
      if (no_cond && data->cond)
      {
        my_message_stderr(0, "Found active lock with not reset "
                          "cond %s: %s", lock_type, where);
        return 1;
      }
      prev= &data->next;
    }
    if (data)
    {
      my_message_stderr(0, "found too many locks at %s: %s",
                        lock_type, where);
      return 1;
    }
  }
  if (prev != list->last)
  {
    my_message_stderr(0, "last didn't point at last lock at %s: %s",
                      lock_type, where);
    return 1;
  }
  return 0;
}
time_t my_time(myf flags)
{
  time_t t;
  /*
    The following loop is here beacuse time() may fail on some systems.
    We're using a hardcoded my_message_stderr() here rather than going
    through the hook in my_message_local() because it's far too easy to
    come full circle with any logging function that writes timestamps ...
  */
  while ((t= time(0)) == (time_t) -1)
  {
    if (flags & MY_WME)
      my_message_stderr(0, "time() call failed", MYF(0));
  }
  return t;
}
Beispiel #3
0
/**
  Issue a message locally (i.e. on the same host the program is
  running on, don't transmit to a client).

  This is the default value for local_message_hook, and therefore
  the default printer for my_message_local(). mysys users should
  not call this directly, but go through my_message_local() instead.

  This printer prepends an Error/Warning/Note label to the string,
  then prints it to stderr using my_message_stderr().
  Since my_message_stderr() appends a '\n', the format string
  should not end in a newline.

  @param ll      log level: (ERROR|WARNING|INFORMATION)_LEVEL
                 the printer may use these to filter for verbosity
  @param format  a format string a la printf. Should not end in '\n'
  @param args    parameters to go with that format string
*/
void my_message_local_stderr(enum loglevel ll,
                             const char *format, va_list args)
{
  char   buff[1024];
  size_t len;

  DBUG_ENTER("my_message_local_stderr");

  len= my_snprintf(buff, sizeof(buff), "[%s] ",
                   (ll == ERROR_LEVEL ? "ERROR" : ll == WARNING_LEVEL ?
                    "Warning" : "Note"));
  my_vsnprintf(buff + len, sizeof(buff) - len, format, args);

  my_message_stderr(0, buff, MYF(0));

  DBUG_VOID_RETURN;
}
static void check_locks(THR_LOCK *lock, const char *where,
			my_bool allow_no_locks)
{
  uint old_found_errors=found_errors;
  DBUG_ENTER("check_locks");

  if (found_errors < MAX_FOUND_ERRORS)
  {
    if (check_lock(&lock->write,"write",where,1,1) |
	check_lock(&lock->write_wait,"write_wait",where,0,0) |
	check_lock(&lock->read,"read",where,0,1) |
	check_lock(&lock->read_wait,"read_wait",where,0,0))
      found_errors++;

    if (found_errors < MAX_FOUND_ERRORS)
    {
      uint count=0;
      THR_LOCK_DATA *data;
      for (data=lock->read.data ; data ; data=data->next)
      {
	if ((int) data->type == (int) TL_READ_NO_INSERT)
	  count++;
        /* Protect against infinite loop. */
        DBUG_ASSERT(count <= lock->read_no_write_count);
      }
      if (count != lock->read_no_write_count)
      {
        found_errors++;
        my_message_stderr(0, "at '%s': Locks read_no_write_count "
                          "was %u when it should have been %u",
                          where, lock->read_no_write_count,count);
      }

      if (!lock->write.data)
      {
        if (!allow_no_locks && !lock->read.data &&
            (lock->write_wait.data || lock->read_wait.data))
        {
          found_errors++;
          my_message_stderr(0, "at '%s': No locks in use but locks "
                            "are in wait queue", where);
        }
        if (!lock->write_wait.data)
        {
          if (!allow_no_locks && lock->read_wait.data)
          {
            found_errors++;
            my_message_stderr(0, "at '%s': No write locks and "
                              "waiting read locks", where);
          }
        }
        else
        {
          if (!allow_no_locks &&
              (((lock->write_wait.data->type == TL_WRITE_CONCURRENT_INSERT ||
                 lock->write_wait.data->type == TL_WRITE_ALLOW_WRITE) &&
                !lock->read_no_write_count)))
          {
            found_errors++;
            my_message_stderr(0, "at '%s': Write lock %d waiting "
                              "while no exclusive read locks",
                              where, (int) lock->write_wait.data->type);
          }
        }
      }
      else
      {						/* Have write lock */
        if (lock->write_wait.data)
        {
          if (!allow_no_locks && 
              lock->write.data->type == TL_WRITE_ALLOW_WRITE &&
              lock->write_wait.data->type == TL_WRITE_ALLOW_WRITE)
          {
            found_errors++;
            my_message_stderr(0, "at '%s': Found WRITE_ALLOW_WRITE "
                              "lock waiting for WRITE_ALLOW_WRITE lock", where);
          }
        }
        if (lock->read.data)
        {
          if (!thr_lock_owner_equal(lock->write.data->owner,
                                    lock->read.data->owner) &&
              ((lock->write.data->type > TL_WRITE_CONCURRENT_INSERT &&
                lock->write.data->type != TL_WRITE_ONLY) ||
               ((lock->write.data->type == TL_WRITE_CONCURRENT_INSERT ||
                 lock->write.data->type == TL_WRITE_ALLOW_WRITE) &&
                lock->read_no_write_count)))
          {
            found_errors++;
            my_message_stderr(0, "at '%s': Found lock of type %d "
                             "that is write and read locked",
                              where, lock->write.data->type);
            DBUG_PRINT("warning",("At '%s': Found lock of type %d that is write and read locked\n",
                                  where, lock->write.data->type));

          }
        }
        if (lock->read_wait.data)
        {
          if (!allow_no_locks && lock->write.data->type <= TL_WRITE_CONCURRENT_INSERT &&
              lock->read_wait.data->type <= TL_READ_HIGH_PRIORITY)
          {
            found_errors++;
            my_message_stderr(0, "at '%s': Found read lock of "
                              "type %d waiting for write lock of type %d",
                              where, (int) lock->read_wait.data->type,
                              (int) lock->write.data->type);
          }
        }
      }
    }
    if (found_errors != old_found_errors)
    {
      DBUG_PRINT("error",("Found wrong lock"));
    }
  }
  DBUG_VOID_RETURN;
}
Beispiel #5
0
void my_end(int infoflag)
{
  /*
    this code is suboptimal to workaround a bug in
    Sun CC: Sun C++ 5.6 2004/06/02 for x86, and should not be
    optimized until this compiler is not in use anymore
  */
  FILE *info_file= DBUG_FILE;
  my_bool print_info= (info_file != stderr);

  if (!my_init_done)
    return;

  /*
    We do not use DBUG_ENTER here, as after cleanup DBUG is no longer
    operational, so we cannot use DBUG_RETURN.
  */
  DBUG_PRINT("info",("Shutting down: infoflag: %d  print_info: %d",
                     infoflag, print_info));
  if (!info_file)
  {
    info_file= stderr;
    print_info= 0;
  }

  if ((infoflag & MY_CHECK_ERROR) || print_info)

  {					/* Test if some file is left open */
    if (my_file_opened | my_stream_opened)
    {
      char ebuff[512];
      my_snprintf(ebuff, sizeof(ebuff), EE(EE_OPEN_WARNING),
                  my_file_opened, my_stream_opened);
      my_message_stderr(EE_OPEN_WARNING, ebuff, ME_BELL);
      DBUG_PRINT("error", ("%s", ebuff));
      my_print_open_files();
    }
  }
  free_charsets();
  my_error_unregister_all();
  my_once_free();

  if ((infoflag & MY_GIVE_INFO) || print_info)
  {
#ifdef HAVE_GETRUSAGE
    struct rusage rus;
#ifdef HAVE_purify
    /* Purify assumes that rus is uninitialized after getrusage call */
    bzero((char*) &rus, sizeof(rus));
#endif
    if (!getrusage(RUSAGE_SELF, &rus))
      fprintf(info_file,"\n\
User time %.2f, System time %.2f\n\
Maximum resident set size %ld, Integral resident set size %ld\n\
Non-physical pagefaults %ld, Physical pagefaults %ld, Swaps %ld\n\
Blocks in %ld out %ld, Messages in %ld out %ld, Signals %ld\n\
Voluntary context switches %ld, Involuntary context switches %ld\n",
	      (rus.ru_utime.tv_sec * SCALE_SEC +
	       rus.ru_utime.tv_usec / SCALE_USEC) / 100.0,
	      (rus.ru_stime.tv_sec * SCALE_SEC +
	       rus.ru_stime.tv_usec / SCALE_USEC) / 100.0,
	      rus.ru_maxrss, rus.ru_idrss,
	      rus.ru_minflt, rus.ru_majflt,
	      rus.ru_nswap, rus.ru_inblock, rus.ru_oublock,
	      rus.ru_msgsnd, rus.ru_msgrcv, rus.ru_nsignals,
	      rus.ru_nvcsw, rus.ru_nivcsw);
#endif
#if defined(__WIN__) && defined(_MSC_VER)
   _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
   _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDERR );
   _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
   _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDERR );
   _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
   _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDERR );
   _CrtCheckMemory();
   _CrtDumpMemoryLeaks();
#endif
  }

  if (!(infoflag & MY_DONT_FREE_DBUG))
  {
    DBUG_END();                /* Must be done before my_thread_end */
  }

  my_thread_end();
  my_thread_global_end();
#if defined(SAFE_MUTEX)
  /*
    Check on destroying of mutexes. A few may be left that will get cleaned
    up by C++ destructors
  */
  safe_mutex_end((infoflag & (MY_GIVE_INFO | MY_CHECK_ERROR)) ? stderr :
                 (FILE *) 0);
#endif /* defined(SAFE_MUTEX) */

#ifdef __WIN__
  if (have_tcpip)
    WSACleanup();
#endif /* __WIN__ */

  my_init_done=0;
} /* my_end */