Esempio n. 1
0
int
pthread_tryjoin_np (
     pthread_t threadid,
     void **thread_return)
{
  struct pthread *self;
  struct pthread *pd = (struct pthread *) threadid;

  /* Make sure the descriptor is valid.  */
  if (DEBUGGING_P && __find_in_stack_list (pd) == NULL)
    /* Not a valid thread handle.  */
    return ESRCH;

  /* Is the thread joinable?.  */
  if (IS_DETACHED (pd))
    /* We cannot wait for the thread.  */
    return EINVAL;

  self = THREAD_SELF;
  if (pd == self || self->joinid == pd)
    /* This is a deadlock situation.  The threads are waiting for each
       other to finish.  Note that this is a "may" error.  To be 100%
       sure we catch this error we would have to lock the data
       structures but it is not necessary.  In the unlikely case that
       two threads are really caught in this situation they will
       deadlock.  It is the programmer's problem to figure this
       out.  */
    return EDEADLK;

  /* Return right away if the thread hasn't terminated yet.  */
  if (pd->tid != 0)
    return EBUSY;

  /* Wait for the thread to finish.  If it is already locked something
     is wrong.  There can only be one waiter.  */
  if (atomic_compare_and_exchange_bool_acq (&pd->joinid, self, NULL))
    /* There is already somebody waiting for the thread.  */
    return EINVAL;

  /* Store the return value if the caller is interested.  */
  if (thread_return != NULL)
    *thread_return = pd->result;


  /* Free the TCB.  */
  __free_tcb (pd);

  return 0;
}
Esempio n. 2
0
void WorkspacePane::DoShowTab(bool show, const wxString& title)
{
    if(!show) {
        for(size_t i = 0; i < m_book->GetPageCount(); i++) {
            if(m_book->GetPageText(i) == title) {
                // we've got a match
                m_book->RemovePage(i);
                wxWindow* win = DoGetControlByName(title);
                if(win) {
                    win->Show(false);
                }
                break;
            }
        }
    } else {
        for(size_t i = 0; i < m_book->GetPageCount(); i++) {
            if(m_book->GetPageText(i) == title) {
                // requested to add a page which already exists
                return;
            }
        }

        // Fetch the list of detached panes
        // If the mainframe is NULL, read the
        // list from the disk, otherwise use the
        // dockable pane menu

        // Read it from the disk
        DetachedPanesInfo dpi;
        EditorConfigST::Get()->ReadObject(wxT("DetachedPanesList"), &dpi);
        wxArrayString detachedPanes;
        detachedPanes = dpi.GetPanes();

        if(IS_DETACHED(title)) return;

        wxWindow* win = DoGetControlByName(title);
        if(win) {
            win->Show(true);
            m_book->InsertPage(0, win, title, true);
        }
    }
}
Esempio n. 3
0
int
pthread_getattr_np (
     pthread_t thread_id,
     pthread_attr_t *attr)
{
  struct pthread *thread = (struct pthread *) thread_id;
  struct pthread_attr *iattr = (struct pthread_attr *) attr;
  int ret = 0;

  lll_lock (thread->lock, LLL_PRIVATE);

  /* The thread library is responsible for keeping the values in the
     thread desriptor up-to-date in case the user changes them.  */
  memcpy (&iattr->schedparam, &thread->schedparam,
	  sizeof (struct sched_param));
  iattr->schedpolicy = thread->schedpolicy;

  /* Clear the flags work.  */
  iattr->flags = thread->flags;

  /* The thread might be detached by now.  */
  if (IS_DETACHED (thread))
    iattr->flags |= ATTR_FLAG_DETACHSTATE;

  /* This is the guardsize after adjusting it.  */
  iattr->guardsize = thread->reported_guardsize;

  /* The sizes are subject to alignment.  */
  if (__builtin_expect (thread->stackblock != NULL, 1))
    {
      iattr->stacksize = thread->stackblock_size;
      iattr->stackaddr = (char *) thread->stackblock + iattr->stacksize;
    }
  else
    {
      /* No stack information available.  This must be for the initial
	 thread.  Get the info in some magical way.  */
      assert (abs (thread->pid) == thread->tid);

      /* Stack size limit.  */
      struct rlimit rl;

      /* The safest way to get the top of the stack is to read
	 /proc/self/maps and locate the line into which
	 __libc_stack_end falls.  */
      FILE *fp = fopen ("/proc/self/maps", "rc");
      if (fp == NULL)
	ret = errno;
      /* We need the limit of the stack in any case.  */
      else
	{
	  if (getrlimit (RLIMIT_STACK, &rl) != 0)
	    ret = errno;
	  else
	    {
	      /* We need no locking.  */
	      __fsetlocking (fp, FSETLOCKING_BYCALLER);

	      /* Until we found an entry (which should always be the case)
		 mark the result as a failure.  */
	      ret = ENOENT;

	      char *line = NULL;
	      size_t linelen = 0;
	      uintptr_t last_to = 0;

	      while (! feof_unlocked (fp))
		{
		  if (getdelim (&line, &linelen, '\n', fp) <= 0)
		    break;

		  uintptr_t from;
		  uintptr_t to;
		  if (sscanf (line, "%" SCNxPTR "-%" SCNxPTR, &from, &to) != 2)
		    continue;
		  if (from <= (uintptr_t) __libc_stack_end
		      && (uintptr_t) __libc_stack_end < to)
		    {
		      /* Found the entry.  Now we have the info we need.  */
		      iattr->stacksize = rl.rlim_cur;
		      iattr->stackaddr = (void *) to;

		      /* The limit might be too high.  */
		      if ((size_t) iattr->stacksize
			  > (size_t) iattr->stackaddr - last_to)
			iattr->stacksize = (size_t) iattr->stackaddr - last_to;

		      /* We succeed and no need to look further.  */
		      ret = 0;
		      break;
		    }
		  last_to = to;
		}

	      free (line);
	    }

	  fclose (fp);
	}
    }

  iattr->flags |= ATTR_FLAG_STACKADDR;

  if (ret == 0)
    {
      size_t size = 16;
      cpu_set_t *cpuset = NULL;

      do
	{
	  size <<= 1;

	  void *newp = realloc (cpuset, size);
	  if (newp == NULL)
	    {
	      ret = ENOMEM;
	      break;
	    }
	  cpuset = (cpu_set_t *) newp;

	  ret = __pthread_getaffinity_np (thread_id, size, cpuset);
	}
      /* Pick some ridiculous upper limit.  Is 8 million CPUs enough?  */
      while (ret == EINVAL && size < 1024 * 1024);

      if (ret == 0)
	{
	  iattr->cpuset = cpuset;
	  iattr->cpusetsize = size;
	}
      else
	{
	  free (cpuset);
	  if (ret == ENOSYS)
	    {
	      /* There is no such functionality.  */
	      ret = 0;
	      iattr->cpuset = NULL;
	      iattr->cpusetsize = 0;
	    }
	}
    }

  lll_unlock (thread->lock, LLL_PRIVATE);

  return ret;
}
Esempio n. 4
0
static int
do_clone (struct pthread *pd, const struct pthread_attr *attr,
	  int clone_flags, int (*fct) (void *), STACK_VARIABLES_PARMS,
	  int stopped)
{
#ifdef PREPARE_CREATE
  PREPARE_CREATE;
#endif

  if (stopped)
    /* We Make sure the thread does not run far by forcing it to get a
       lock.  We lock it here too so that the new thread cannot continue
       until we tell it to.  */
    lll_lock (pd->lock);

  /* One more thread.  We cannot have the thread do this itself, since it
     might exist but not have been scheduled yet by the time we've returned
     and need to check the value to behave correctly.  We must do it before
     creating the thread, in case it does get scheduled first and then
     might mistakenly think it was the only thread.  In the failure case,
     we momentarily store a false value; this doesn't matter because there
     is no kosher thing a signal handler interrupting us right here can do
     that cares whether the thread count is correct.  */
  atomic_increment (&__nptl_nthreads);

  if (ARCH_CLONE (fct, STACK_VARIABLES_ARGS, clone_flags,
		  pd, &pd->tid, TLS_VALUE, &pd->tid) == -1)
    {
      atomic_decrement (&__nptl_nthreads); /* Oops, we lied for a second.  */

      /* Failed.  If the thread is detached, remove the TCB here since
	 the caller cannot do this.  The caller remembered the thread
	 as detached and cannot reverify that it is not since it must
	 not access the thread descriptor again.  */
      if (IS_DETACHED (pd))
	__deallocate_stack (pd);

      return errno;
    }

  /* Now we have the possibility to set scheduling parameters etc.  */
  if (__builtin_expect (stopped != 0, 0))
    {
      INTERNAL_SYSCALL_DECL (err);
      int res = 0;

      /* Set the affinity mask if necessary.  */
      if (attr->cpuset != NULL)
	{
	  res = INTERNAL_SYSCALL (sched_setaffinity, err, 3, pd->tid,
				  sizeof (cpu_set_t), attr->cpuset);

	  if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (res, err), 0))
	    {
	      /* The operation failed.  We have to kill the thread.  First
		 send it the cancellation signal.  */
	      INTERNAL_SYSCALL_DECL (err2);
	    err_out:
#if __ASSUME_TGKILL
	      (void) INTERNAL_SYSCALL (tgkill, err2, 3,
				       THREAD_GETMEM (THREAD_SELF, pid),
				       pd->tid, SIGCANCEL);
#else
	      (void) INTERNAL_SYSCALL (tkill, err2, 2, pd->tid, SIGCANCEL);
#endif

	      return (INTERNAL_SYSCALL_ERROR_P (res, err)
		      ? INTERNAL_SYSCALL_ERRNO (res, err)
		      : 0);
	    }
	}

      /* Set the scheduling parameters.  */
      if ((attr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0)
	{
	  res = INTERNAL_SYSCALL (sched_setscheduler, err, 3, pd->tid,
				  pd->schedpolicy, &pd->schedparam);

	  if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (res, err), 0))
	    goto err_out;
	}
    }

  /* We now have for sure more than one thread.  The main thread might
     not yet have the flag set.  No need to set the global variable
     again if this is what we use.  */
  THREAD_SETMEM (THREAD_SELF, header.multiple_threads, 1);

  return 0;
}
Esempio n. 5
0
void DebuggerPane::CreateGUIControls()
{
    wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
    SetSizer(mainSizer);

    long style = (kNotebook_Default | kNotebook_AllowDnD);
    if(!EditorConfigST::Get()->GetOptions()->GetWorkspaceTabsDirection()) {
        style |= kNotebook_BottomTabs;
    }
    if(EditorConfigST::Get()->GetOptions()->IsTabColourDark()) {
        style &= ~kNotebook_LightTabs;
        style |= kNotebook_DarkTabs;
    }
    if(EditorConfigST::Get()->GetOptions()->IsMouseScrollSwitchTabs()) {
        style |= kNotebook_MouseScrollSwitchTabs;
    }
    style |= kNotebook_UnderlineActiveTab;

    GeneralImages img;
    m_book = new Notebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, style);
    mainSizer->Add(m_book, 1, wxEXPAND | wxALL, 0);

    // Calculate the widthest tab (the one with the 'Call Stack' label)
    int xx, yy;
    wxFont fnt = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
    wxWindow::GetTextExtent(_("Breakpoints"), &xx, &yy, NULL, NULL, &fnt);

    // load list of detached panes
    wxArrayString detachedPanes;
    DetachedPanesInfo dpi;
    EditorConfigST::Get()->ReadObject(wxT("DetachedPanesList"), &dpi);
    detachedPanes = dpi.GetPanes();

    wxString name;
    wxBitmap bmp;
    name = wxGetTranslation(LOCALS);
    bmp = wxXmlResource::Get()->LoadBitmap(wxT("locals_view"));
    // Add the 'Locals View'
    if(IS_DETACHED(name)) {
        DockablePane* cp = new DockablePane(GetParent(), m_book, name, false, bmp, wxSize(200, 200));
        m_localsTable = new LocalsTable(cp);
        cp->SetChildNoReparent(m_localsTable);

    } else {
        m_localsTable = new LocalsTable(m_book);
        m_book->AddPage(m_localsTable, name, false, bmp);
    }

    // Add the 'watches View'
    name = wxGetTranslation(WATCHES);
    bmp = wxXmlResource::Get()->LoadBitmap(wxT("watches"));
    if(IS_DETACHED(name)) {
        DockablePane* cp = new DockablePane(GetParent(), m_book, name, false, bmp, wxSize(200, 200));
        m_watchesTable = new WatchesTable(cp);
        cp->SetChildNoReparent(m_watchesTable);

    } else {
        m_watchesTable = new WatchesTable(m_book);
        m_book->AddPage(m_watchesTable, name, false, bmp);
    }

    // Add the 'ASCII Viewer'
    name = wxGetTranslation(ASCII_VIEWER);
    bmp = wxXmlResource::Get()->LoadBitmap(wxT("text_view"));
    if(IS_DETACHED(name)) {
        DockablePane* cp = new DockablePane(GetParent(), m_book, name, false, bmp, wxSize(200, 200));
        m_asciiViewer = new DebuggerAsciiViewer(cp);
        cp->SetChildNoReparent(m_asciiViewer);

    } else {
        m_asciiViewer = new DebuggerAsciiViewer(m_book);
        m_book->AddPage(m_asciiViewer, name, false, bmp);
    }

    // Add the 'Call Stack'
    name = wxGetTranslation(FRAMES);
    bmp = wxXmlResource::Get()->LoadBitmap(wxT("frames"));
    if(IS_DETACHED(name)) {
        DockablePane* cp = new DockablePane(GetParent(), m_book, name, false, bmp, wxSize(200, 200));
        m_frameList = new DebuggerCallstackView(cp);
        cp->SetChildNoReparent(m_frameList);

    } else {
        m_frameList = new DebuggerCallstackView(m_book);
        m_book->AddPage(m_frameList, name, false, bmp);
    }

    // Add the 'Breakpoints'
    name = wxGetTranslation(BREAKPOINTS);
    bmp = wxXmlResource::Get()->LoadBitmap(wxT("breakpoint"));
    if(IS_DETACHED(name)) {
        DockablePane* cp = new DockablePane(GetParent(), m_book, name, false, bmp, wxSize(200, 200));
        m_breakpoints = new BreakpointDlg(cp);
        cp->SetChildNoReparent(m_breakpoints);

    } else {
        m_breakpoints = new BreakpointDlg(m_book);
        m_book->AddPage(m_breakpoints, name, false, bmp);
    }

    // Add the 'Threads'
    name = wxGetTranslation(THREADS);
    bmp = wxXmlResource::Get()->LoadBitmap(wxT("threads"));
    if(IS_DETACHED(name)) {
        DockablePane* cp = new DockablePane(GetParent(), m_book, name, false, bmp, wxSize(200, 200));
        m_threads = new ThreadListPanel(cp);
        cp->SetChildNoReparent(m_threads);

    } else {
        m_threads = new ThreadListPanel(m_book);
        m_book->AddPage(m_threads, name, false, bmp);
    }

    // Add the 'Memory View'
    name = wxGetTranslation(MEMORY);
    bmp = wxXmlResource::Get()->LoadBitmap(wxT("memory_view"));
    if(IS_DETACHED(name)) {
        DockablePane* cp = new DockablePane(GetParent(), m_book, name, false, bmp, wxSize(200, 200));
        m_memory = new MemoryView(cp);
        cp->SetChildNoReparent(m_memory);

    } else {
        m_memory = new MemoryView(m_book);
        m_book->AddPage(m_memory, name, false, bmp);
    }

    // Add the "Output" tab
    name = wxGetTranslation(DEBUGGER_OUTPUT);
    bmp = wxXmlResource::Get()->LoadBitmap(wxT("debugger_tab"));
    if(IS_DETACHED(name)) {
        DockablePane* cp = new DockablePane(GetParent(), m_book, name, false, bmp, wxSize(200, 200));
        m_outputDebug = new DebugTab(cp, wxID_ANY, wxGetTranslation(DEBUGGER_OUTPUT));
        cp->SetChildNoReparent(m_outputDebug);

    } else {
        m_outputDebug = new DebugTab(m_book, wxID_ANY, wxGetTranslation(DEBUGGER_OUTPUT));
        m_book->AddPage(m_outputDebug, name, false, bmp);
    }

    // Add the "Output" tab
    name = wxGetTranslation(DISASSEMBLY);
    bmp = img.Bitmap("dbgAsm");
    if(IS_DETACHED(name)) {
        DockablePane* cp = new DockablePane(GetParent(), m_book, name, false, bmp, wxSize(200, 200));
        m_disassemble = new DebuggerDisassemblyTab(cp, wxGetTranslation(DISASSEMBLY));
        cp->SetChildNoReparent(m_disassemble);

    } else {
        m_disassemble = new DebuggerDisassemblyTab(m_book, wxGetTranslation(DISASSEMBLY));
        m_book->AddPage(m_disassemble, name, false, bmp);
    }
    m_book->Bind(wxEVT_BOOK_PAGE_CHANGED, &DebuggerPane::OnPageChanged, this);
    m_initDone = true;
}
Esempio n. 6
0
void WorkspacePane::CreateGUIControls()
{
    wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
    SetSizer(mainSizer);

// add notebook for tabs
#ifdef __WXOSX__
    long style = (kNotebook_Default | kNotebook_AllowDnD | kNotebook_LeftTabs);
#else
    long style = (kNotebook_Default | kNotebook_AllowDnD);
#endif
    if(EditorConfigST::Get()->GetOptions()->IsTabColourDark()) {
        style &= ~kNotebook_LightTabs;
        style |= kNotebook_DarkTabs;
    }
    style |= kNotebook_UnderlineActiveTab;
    if(EditorConfigST::Get()->GetOptions()->IsMouseScrollSwitchTabs()) {
        style |= kNotebook_MouseScrollSwitchTabs;
    }
    m_book = new Notebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, style);
    m_book->SetTabDirection(EditorConfigST::Get()->GetOptions()->GetWorkspaceTabsDirection());
    m_book->SetArt(GetNotebookRenderer());

    // Calculate the widest tab (the one with the 'Workspace' label)
    int xx, yy;
    wxFont fnt = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
    wxWindow::GetTextExtent(_("Workspace"), &xx, &yy, NULL, NULL, &fnt);

    mainSizer->Add(m_book, 1, wxEXPAND | wxALL, 0);

    // Add the parsing progress controls
    m_staticText = new wxStaticText(this, wxID_ANY, _("Parsing workspace..."));
    mainSizer->Add(m_staticText, 0, wxEXPAND | wxALL, 2);

    m_parsingProgress =
        new wxGauge(this, wxID_ANY, 100, wxDefaultPosition, wxSize(-1, 15), wxGA_HORIZONTAL | wxGA_SMOOTH);
    mainSizer->Add(m_parsingProgress, 0, wxEXPAND | wxALL, 1);
    m_parsingProgress->Hide();
    m_staticText->Hide();

    // create tabs (possibly detached)
    DetachedPanesInfo dpi;
    EditorConfigST::Get()->ReadObject(wxT("DetachedPanesList"), &dpi);

    wxArrayString detachedPanes;
    detachedPanes = dpi.GetPanes();

    // Add the workspace tab
    wxString name;

    // the IManager instance
    IManager* mgr = PluginManager::Get();

    name = _("Workspace");
    if(IS_DETACHED(name)) {
        DockablePane* cp = new DockablePane(GetParent(), m_book, name, false, wxNullBitmap, wxSize(200, 200));
        m_workspaceTab = new WorkspaceTab(cp, name);
        cp->SetChildNoReparent(m_workspaceTab);
    } else {
        m_workspaceTab = new WorkspaceTab(m_book, name);
        m_book->AddPage(m_workspaceTab, name, true, wxNullBitmap);
    }
    m_tabs.insert(std::make_pair(name, Tab(name, m_workspaceTab)));
    mgr->AddWorkspaceTab(name);

    // Add the explorer tab
    name = _("Explorer");
    if(IS_DETACHED(name)) {
        DockablePane* cp = new DockablePane(GetParent(), m_book, name, false, wxNullBitmap, wxSize(200, 200));
        m_explorer = new FileExplorer(cp, name);
        cp->SetChildNoReparent(m_explorer);
    } else {
        m_explorer = new FileExplorer(m_book, name);
        m_book->AddPage(m_explorer, name, false);
    }
    m_tabs.insert(std::make_pair(name, Tab(name, m_explorer)));
    mgr->AddWorkspaceTab(name);

    // Add the "File Explorer" view to the list of files managed by the workspace-view
    m_workspaceTab->GetView()->AddPage(m_explorer, _("File Explorer"), false);

// Add the Open Windows Panel (Tabs)
#ifndef __WXOSX__
    name = _("Tabs");
    if(IS_DETACHED(name)) {
        DockablePane* cp = new DockablePane(GetParent(), m_book, name, false, wxNullBitmap, wxSize(200, 200));
        m_openWindowsPane = new OpenWindowsPanel(cp, name);
        cp->SetChildNoReparent(m_openWindowsPane);
    } else {
        m_openWindowsPane = new OpenWindowsPanel(m_book, name);
        m_book->AddPage(m_openWindowsPane, name, false);
    }
    m_tabs.insert(std::make_pair(name, Tab(name, m_openWindowsPane)));
    mgr->AddWorkspaceTab(name);
#endif

    // Add the Tabgroups tab
    name = _("Tabgroups");
    if(IS_DETACHED(name)) {
        DockablePane* cp = new DockablePane(GetParent(), m_book, name, false, wxNullBitmap, wxSize(200, 200));
        m_TabgroupsPane = new TabgroupsPane(cp, name);
        cp->SetChildNoReparent(m_TabgroupsPane);
    } else {
        m_TabgroupsPane = new TabgroupsPane(m_book, name);
        m_book->AddPage(m_TabgroupsPane, name, false);
    }
    m_tabs.insert(std::make_pair(name, Tab(name, m_TabgroupsPane)));
    mgr->AddWorkspaceTab(name);

    if(m_book->GetPageCount() > 0) {
        m_book->SetSelection((size_t)0);
    }
    m_mgr->Update();
}
Esempio n. 7
0
int
pthread_timedjoin_np (
     pthread_t threadid,
     void **thread_return,
     const struct timespec *abstime)
{
  struct pthread *self;
  struct pthread *pd = (struct pthread *) threadid;
  int result;

  /* Make sure the descriptor is valid.  */
  if (INVALID_NOT_TERMINATED_TD_P (pd))
    /* Not a valid thread handle.  */
    return ESRCH;

  /* Is the thread joinable?.  */
  if (IS_DETACHED (pd))
    /* We cannot wait for the thread.  */
    return EINVAL;

  self = THREAD_SELF;
  if (pd == self || self->joinid == pd)
    /* This is a deadlock situation.  The threads are waiting for each
       other to finish.  Note that this is a "may" error.  To be 100%
       sure we catch this error we would have to lock the data
       structures but it is not necessary.  In the unlikely case that
       two threads are really caught in this situation they will
       deadlock.  It is the programmer's problem to figure this
       out.  */
    return EDEADLK;

  /* Wait for the thread to finish.  If it is already locked something
     is wrong.  There can only be one waiter.  */
  if (__builtin_expect (atomic_compare_and_exchange_bool_acq (&pd->joinid,
							      self, NULL), 0))
    /* There is already somebody waiting for the thread.  */
    return EINVAL;


  /* During the wait we change to asynchronous cancellation.  If we
     are cancelled the thread we are waiting for must be marked as
     un-wait-ed for again.  */
  pthread_cleanup_push (cleanup, &pd->joinid);

  /* Switch to asynchronous cancellation.  */
  int oldtype = CANCEL_ASYNC ();


  /* Wait for the child.  */
  result = lll_timedwait_tid (pd->tid, abstime);


  /* Restore cancellation mode.  */
  CANCEL_RESET (oldtype);

  /* Remove the handler.  */
  pthread_cleanup_pop (0);


  /* We might have timed out.  */
  if (result == 0)
    {
      /* Store the return value if the caller is interested.  */
      if (thread_return != NULL)
	*thread_return = pd->result;


      /* Free the TCB.  */
      __free_tcb (pd);
    }
  else
    pd->joinid = NULL;

  return result;
}
Esempio n. 8
0
void WorkspacePane::CreateGUIControls()
{
    wxBoxSizer *mainSizer = new wxBoxSizer(wxVERTICAL);
    SetSizer(mainSizer);

    // add notebook for tabs
    long bookStyle = wxVB_LEFT | wxAUI_NB_WINDOWLIST_BUTTON;
    m_book = new Notebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, bookStyle);

    // Calculate the widest tab (the one with the 'Workspace' label)
    int xx, yy;
    wxFont fnt = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
    wxWindow::GetTextExtent(_("Workspace"), &xx, &yy, NULL, NULL, &fnt);

    mainSizer->Add(m_book, 1, wxEXPAND | wxALL, 0);

    // Add the parsing progress controls
    m_staticText = new wxStaticText(this, wxID_ANY, _("Parsing workspace..."));
    mainSizer->Add(m_staticText, 0, wxEXPAND|wxALL, 2);

    m_parsingProgress = new wxGauge(this, wxID_ANY, 100, wxDefaultPosition, wxSize(-1, 15), wxGA_HORIZONTAL|wxGA_SMOOTH);
    mainSizer->Add(m_parsingProgress, 0, wxEXPAND|wxALL, 1);
    m_parsingProgress->Hide();
    m_staticText->Hide();

    // create tabs (possibly detached)
    DetachedPanesInfo dpi;
    EditorConfigST::Get()->ReadObject(wxT("DetachedPanesList"), &dpi);


    wxArrayString detachedPanes;
    detachedPanes = dpi.GetPanes();

    // Add the workspace tab
    wxString  name;

    name = _("Workspace");
    if(IS_DETACHED(name)) {
        DockablePane *cp = new DockablePane(GetParent(), m_book, name, wxNullBitmap, wxSize(200, 200));
        m_workspaceTab = new WorkspaceTab(cp, name);
        cp->SetChildNoReparent(m_workspaceTab);
    } else {
        m_workspaceTab = new WorkspaceTab(m_book, name);
        m_book->AddPage(m_workspaceTab, name, true, wxNullBitmap);
    }

    // Add the explorer tab
    name = _("Explorer");
    if(IS_DETACHED(name)) {
        DockablePane *cp = new DockablePane(GetParent(), m_book, name, wxNullBitmap, wxSize(200, 200));
        m_explorer = new FileExplorer(cp, name);
        cp->SetChildNoReparent(m_explorer);
    } else {
        m_explorer = new FileExplorer(m_book, name);
        m_book->AddPage(m_explorer, name, false);
    }

    // Add the Open Windows Panel (Tabs)
    name = _("Tabs");
    if(IS_DETACHED(name)) {
        DockablePane *cp = new DockablePane(GetParent(), m_book,  name, wxNullBitmap, wxSize(200, 200));
        m_openWindowsPane = new OpenWindowsPanel(cp, name);
        cp->SetChildNoReparent(m_openWindowsPane);
    } else {
        m_openWindowsPane = new OpenWindowsPanel(m_book, name);
        m_book->AddPage(m_openWindowsPane, name, false);
    }

    // Add the Tabgroups tab
    name = _("Tabgroups");
    if(IS_DETACHED(name)) {
        DockablePane *cp = new DockablePane(GetParent(), m_book,  name, wxNullBitmap, wxSize(200, 200));
        m_TabgroupsPane = new TabgroupsPane(cp, name);
        cp->SetChildNoReparent(m_TabgroupsPane);
    } else {
        m_TabgroupsPane = new TabgroupsPane(m_book, name);
        m_book->AddPage(m_TabgroupsPane, name, false);
    }

    if (m_book->GetPageCount() > 0) {
        m_book->SetSelection((size_t)0);
    }
    UpdateTabs();
    m_mgr->Update();
}
Esempio n. 9
0
static int
do_clone (struct pthread *pd, const struct pthread_attr *attr,
	  int clone_flags, int (*fct) (void *), STACK_VARIABLES_PARMS,
	  int stopped)
{
#if 0
  PREPARE_CREATE;
#endif

  if (__builtin_expect (stopped != 0, 0))
    /* We make sure the thread does not run far by forcing it to get a
       lock.  We lock it here too so that the new thread cannot continue
       until we tell it to.  */
    lll_lock (pd->lock, LLL_PRIVATE);

  /* One more thread.  We cannot have the thread do this itself, since it
     might exist but not have been scheduled yet by the time we've returned
     and need to check the value to behave correctly.  We must do it before
     creating the thread, in case it does get scheduled first and then
     might mistakenly think it was the only thread.  In the failure case,
     we momentarily store a false value; this doesn't matter because there
     is no kosher thing a signal handler interrupting us right here can do
     that cares whether the thread count is correct.  */
  atomic_increment (&__nptl_nthreads);

#if !defined(__native_client__) && !defined(__ZRT_HOST)
#error "This code was changed to work only in Native Client"
#endif

  /* Native Client does not have a notion of a thread ID, so we make
     one up.  This must be small enough to leave space for number identifying
     the clock.  Use CLOCK_IDFIELD_SIZE to guarantee that.  */
  pd->tid = ((unsigned int) pd) >> CLOCK_IDFIELD_SIZE;

  /* Native Client syscall thread_create does not push return address onto stack
     as opposed to the kernel.  We emulate this behavior on x86-64 to meet the
     ABI requirement ((%rsp + 8) mod 16 == 0).  On x86-32 the attribute
     'force_align_arg_pointer' does the same for start_thread ().  */
#ifdef __x86_64__
  STACK_VARIABLES_ARGS -= 8;
#endif

  if (__nacl_irt_thread_create (fct, STACK_VARIABLES_ARGS, pd) != 0)
    {
      pd->tid = 0;
      atomic_decrement (&__nptl_nthreads); /* Oops, we lied for a second.  */

      /* Failed.  If the thread is detached, remove the TCB here since
	 the caller cannot do this.  The caller remembered the thread
	 as detached and cannot reverify that it is not since it must
	 not access the thread descriptor again.  */
      if (IS_DETACHED (pd))
	__deallocate_stack (pd);

      /* We have to translate error codes.  */
      return errno == ENOMEM ? EAGAIN : errno;
    }

  /* Now we have the possibility to set scheduling parameters etc.  */
  if (__builtin_expect (stopped != 0, 0))
    {
      INTERNAL_SYSCALL_DECL (err);
      int res = 0;

      /* Set the affinity mask if necessary.  */
      if (attr->cpuset != NULL)
	{
	  res = INTERNAL_SYSCALL (sched_setaffinity, err, 3, pd->tid,
				  attr->cpusetsize, attr->cpuset);

	  if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (res, err), 0))
	    {
	      /* The operation failed.  We have to kill the thread.  First
		 send it the cancellation signal.  */
	      INTERNAL_SYSCALL_DECL (err2);
	    err_out:
#if __ASSUME_TGKILL
	      (void) INTERNAL_SYSCALL (tgkill, err2, 3,
				       THREAD_GETMEM (THREAD_SELF, pid),
				       pd->tid, SIGCANCEL);
#else
	      (void) INTERNAL_SYSCALL (tkill, err2, 2, pd->tid, SIGCANCEL);
#endif

	      return (INTERNAL_SYSCALL_ERROR_P (res, err)
		      ? INTERNAL_SYSCALL_ERRNO (res, err)
		      : 0);
	    }
	}

      /* Set the scheduling parameters.  */
      if ((attr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0)
	{
	  res = INTERNAL_SYSCALL (sched_setscheduler, err, 3, pd->tid,
				  pd->schedpolicy, &pd->schedparam);

	  if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (res, err), 0))
	    goto err_out;
	}
    }

  /* We now have for sure more than one thread.  The main thread might
     not yet have the flag set.  No need to set the global variable
     again if this is what we use.  */
  THREAD_SETMEM (THREAD_SELF, header.multiple_threads, 1);

  return 0;
}