Exemple #1
0
static int snd_pcm_shm_new_rbptr(snd_pcm_t *pcm, snd_pcm_shm_t *shm,
				 snd_pcm_rbptr_t *rbptr, volatile snd_pcm_shm_rbptr_t *shm_rbptr)
{
	if (!shm_rbptr->use_mmap) {
		if (&pcm->hw == rbptr)
			snd_pcm_set_hw_ptr(pcm, &shm_rbptr->ptr, -1, 0);
		else
			snd_pcm_set_appl_ptr(pcm, &shm_rbptr->ptr, -1, 0);
	} else {
		void *ptr;
		size_t mmap_size, mmap_offset, offset;
		int fd;
		long result;
		
		shm->ctrl->cmd = &pcm->hw == rbptr ? SND_PCM_IOCTL_HW_PTR_FD : SND_PCM_IOCTL_APPL_PTR_FD;
		result = snd_pcm_shm_action_fd0(pcm, &fd);
		if (result < 0)
			return result;
		mmap_size = page_ptr(shm_rbptr->offset, sizeof(snd_pcm_uframes_t), &offset, &mmap_offset);
		ptr = mmap(NULL, mmap_size, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, fd, mmap_offset);
		if (ptr == MAP_FAILED || ptr == NULL) {
			SYSERR("shm rbptr mmap failed");
			return -errno;
		}
		if (&pcm->hw == rbptr)
			snd_pcm_set_hw_ptr(pcm, (snd_pcm_uframes_t *)((char *)ptr + offset), fd, shm_rbptr->offset);
		else
			snd_pcm_set_appl_ptr(pcm, (snd_pcm_uframes_t *)((char *)ptr + offset), fd, shm_rbptr->offset);
	}
	return 0;
}
	bin_index_t::page_ptr bin_index_t::file_node::create_page() const
	{
		return page_ptr(new page_t(aligned_key_len,parent.page_max_size));
	}
void
Restore::restore_next(Signal* signal, FilePtr file_ptr)
{
  Uint32 *data, len= 0;
  Uint32 status = file_ptr.p->m_status;
  Uint32 page_count = file_ptr.p->m_pages.getSize();
  do 
  {
    Uint32 left= file_ptr.p->m_bytes_left;
    if (left < 8)
    {
      jam();
      /**
       * Not enough bytes to read header
       */
      break;
    }
    Ptr<GlobalPage> page_ptr(0,0), next_page_ptr(0,0);
    m_global_page_pool.getPtr(page_ptr, file_ptr.p->m_current_page_ptr_i);
    List::Iterator it;
    
    Uint32 pos= file_ptr.p->m_current_page_pos;
    if(status & File::READING_RECORDS)
    {
      jam();
      /**
       * We are reading records
       */
      len= ntohl(* (page_ptr.p->data + pos)) + 1;
      ndbrequire(len < GLOBAL_PAGE_SIZE_WORDS);
    }
    else
    {
      jam();
      /**
       * Section length is in 2 word
       */
      if(pos + 1 == GLOBAL_PAGE_SIZE_WORDS)
      {
        jam();
	/**
	 * But that's stored on next page...
	 *   and since we have atleast 8 bytes left in buffer
	 *   we can be sure that that's in buffer
	 */
	LocalDataBuffer<15> pages(m_databuffer_pool, file_ptr.p->m_pages);
	Uint32 next_page = file_ptr.p->m_current_page_index + 1;
	pages.position(it, next_page % page_count);
	m_global_page_pool.getPtr(next_page_ptr, * it.data);
	len= ntohl(* next_page_ptr.p->data);
      }
      else
      {
        jam();
	len= ntohl(* (page_ptr.p->data + pos + 1));
      }
    }

    if (file_ptr.p->m_status & File::FIRST_READ)
    {
      jam();
      len= 3;
      file_ptr.p->m_status &= ~(Uint32)File::FIRST_READ;
    }
    
    if (4 * len > left)
    {
      jam();

      /**
       * Not enought bytes to read "record"
       */
      if (unlikely((status & File:: FILE_THREAD_RUNNING) == 0))
      {
        crash_during_restore(file_ptr, __LINE__, 0);
      }
      len= 0;
      break;
    }
    
    /**
     * Entire record is in buffer
     */

    if(pos + len >= GLOBAL_PAGE_SIZE_WORDS)
    {
      jam();
      /**
       * But it's split over pages
       */
      if(next_page_ptr.p == 0)
      {
	LocalDataBuffer<15> pages(m_databuffer_pool, file_ptr.p->m_pages);
	Uint32 next_page = file_ptr.p->m_current_page_index + 1;
	pages.position(it, next_page % page_count);
	m_global_page_pool.getPtr(next_page_ptr, * it.data);
      }
      file_ptr.p->m_current_page_ptr_i = next_page_ptr.i;
      file_ptr.p->m_current_page_pos = (pos + len) - GLOBAL_PAGE_SIZE_WORDS;
      file_ptr.p->m_current_page_index = 
	(file_ptr.p->m_current_page_index + 1) % page_count;

      if (len <= GLOBAL_PAGE_SIZE_WORDS)
      {
        jam();
        Uint32 first = (GLOBAL_PAGE_SIZE_WORDS - pos);
        // wl4391_todo removing valgrind overlap warning for now
        memmove(page_ptr.p, page_ptr.p->data+pos, 4 * first);
        memcpy(page_ptr.p->data+first, next_page_ptr.p, 4 * (len - first));
        data= page_ptr.p->data;
      }
      else
      {
        jam();
        /**
         * A table definition can be larger than one page...
         * when that happens copy it out to side buffer
         *
         * First copy part belonging to page_ptr
         * Then copy full middle pages (moving forward in page-list)
         * Last copy last part
         */
        Uint32 save = len;
        assert(len <= NDB_ARRAY_SIZE(m_table_buf));
        Uint32 * dst = m_table_buf;

        /**
         * First
         */
        Uint32 first = (GLOBAL_PAGE_SIZE_WORDS - pos);
        memcpy(dst, page_ptr.p->data+pos, 4 * first);
        len -= first;
        dst += first;

        /**
         * Middle
         */
        while (len > GLOBAL_PAGE_SIZE_WORDS)
        {
          jam();
          memcpy(dst, next_page_ptr.p, 4 * GLOBAL_PAGE_SIZE_WORDS);
          len -= GLOBAL_PAGE_SIZE_WORDS;
          dst += GLOBAL_PAGE_SIZE_WORDS;

          {
            LocalDataBuffer<15> pages(m_databuffer_pool, file_ptr.p->m_pages);
            Uint32 next_page = (file_ptr.p->m_current_page_index + 1) % page_count;
            pages.position(it, next_page % page_count);
            m_global_page_pool.getPtr(next_page_ptr, * it.data);

            file_ptr.p->m_current_page_ptr_i = next_page_ptr.i;
            file_ptr.p->m_current_page_index = next_page;
          }
        }

        /**
         * last
         */
        memcpy(dst, next_page_ptr.p, 4 * len);
        file_ptr.p->m_current_page_pos = len;

        /**
         * Set pointer and len
         */
        len = save;
        data = m_table_buf;
      }
    }
    else
    {
      file_ptr.p->m_current_page_pos = pos + len;
      data= page_ptr.p->data+pos;
    }
    
    file_ptr.p->m_bytes_left -= 4*len;
    
    if(status & File::READING_RECORDS)
    {
      if(len == 1)
      {
	file_ptr.p->m_status = status & ~(Uint32)File::READING_RECORDS;
      }
      else
      {
	parse_record(signal, file_ptr, data, len);
      }
    }
    else
    {
      switch(ntohl(* data)){
      case BackupFormat::FILE_HEADER:
	parse_file_header(signal, file_ptr, data-3, len+3);
	break;
      case BackupFormat::FRAGMENT_HEADER:
	file_ptr.p->m_status = status | File::READING_RECORDS;
	parse_fragment_header(signal, file_ptr, data, len);
	break;
      case BackupFormat::FRAGMENT_FOOTER:
	parse_fragment_footer(signal, file_ptr, data, len);
	break;
      case BackupFormat::TABLE_LIST:
	parse_table_list(signal, file_ptr, data, len);
	break;
      case BackupFormat::TABLE_DESCRIPTION:
	parse_table_description(signal, file_ptr, data, len);
	break;
      case BackupFormat::GCP_ENTRY:
	parse_gcp_entry(signal, file_ptr, data, len);
	break;
      case BackupFormat::EMPTY_ENTRY:
        // skip
        break;
      case 0x4e444242: // 'NDBB'
	if (check_file_version(signal, ntohl(* (data+2))) == 0)
	{
	  break;
	}
      default:
	parse_error(signal, file_ptr, __LINE__, ntohl(* data));
      }
    }
  } while(0);
  
  if(file_ptr.p->m_bytes_left == 0 && status & File::FILE_EOF)
  {
    file_ptr.p->m_status &= ~(Uint32)File::RESTORE_THREAD_RUNNING;
    /**
     * File is finished...
     */
    close_file(signal, file_ptr);
    return;
  }
  
  /**
   * We send an immediate signal to continue the restore, at times this
   * could lead to burning some extra CPU since we might still wait for
   * input from the disk reading. This code is however only executed
   * as part of restarts, so it should be ok to spend some extra CPU
   * to ensure that restarts are quick.
   */
  signal->theData[0] = RestoreContinueB::RESTORE_NEXT;
  signal->theData[1] = file_ptr.i;
  sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
}