<commit_before>/* Copyright 2019 Google LLC. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include "thread_pool.h"

#include <atomic>
#include <chrono>              // NOLINT(build/c++11)
#include <condition_variable>  // NOLINT(build/c++11)
#include <cstdint>
#include <cstdlib>
#include <memory>
#include <mutex>               // NOLINT(build/c++11)
#include <thread>              // NOLINT(build/c++11)

#include "check_macros.h"
#include "wait.h"

namespace ruy {

// A worker thread.
class Thread {
 public:
  enum class State {
    Startup,  // The initial state before the thread main loop runs.
    Ready,    // Is not working, has not yet received new work to do.
    HasWork,  // Has work to do.
    ExitAsSoonAsPossible  // Should exit at earliest convenience.
  };

  explicit Thread(BlockingCounter* counter_to_decrement_when_ready)
      : task_(nullptr),
        state_(State::Startup),
        counter_to_decrement_when_ready_(counter_to_decrement_when_ready) {
    thread_.reset(new std::thread(ThreadFunc, this));
  }

  ~Thread() {
    ChangeState(State::ExitAsSoonAsPossible);
    thread_->join();
  }

  // Changes State; may be called from either the worker thread
  // or the master thread; however, not all state transitions are legal,
  // which is guarded by assertions.
  //
  // The Task argument is to be used only with new_state==HasWork.
  // It specifies the Task being handed to this Thread.
  void ChangeState(State new_state, Task* task = nullptr) {
    state_mutex_.lock();
    State old_state = state_.load(std::memory_order_relaxed);
    RUY_DCHECK(old_state != new_state);
    switch (old_state) {
      case State::Startup:
        RUY_DCHECK(new_state == State::Ready);
        break;
      case State::Ready:
        RUY_DCHECK(new_state == State::HasWork ||
                   new_state == State::ExitAsSoonAsPossible);
        break;
      case State::HasWork:
        RUY_DCHECK(new_state == State::Ready ||
                   new_state == State::ExitAsSoonAsPossible);
        break;
      default:
        abort();
    }
    switch (new_state) {
      case State::Ready:
        if (task_) {
          // Doing work is part of reverting to 'ready' state.
          task_->Run();
          task_ = nullptr;
        }
        break;
      case State::HasWork:
        RUY_DCHECK(!task_);
        task_ = task;
        break;
      default:
        break;
    }
    state_.store(new_state, std::memory_order_relaxed);
    state_cond_.notify_all();
    state_mutex_.unlock();
    if (new_state == State::Ready) {
      counter_to_decrement_when_ready_->DecrementCount();
    }
  }

  static void ThreadFunc(Thread* arg) { arg->ThreadFuncImpl(); }

  // Called by the master thead to give this thread work to do.
  void StartWork(Task* task) { ChangeState(State::HasWork, task); }

 private:
  // Thread entry point.
  void ThreadFuncImpl() {
    ChangeState(State::Ready);

    // Thread main loop
    while (true) {
      // In the 'Ready' state, we have nothing to do but to wait until
      // we switch to another state.
      const auto& condition = [this]() {
        return state_.load(std::memory_order_acquire) != State::Ready;
      };
      WaitUntil(condition, &state_cond_, &state_mutex_);

      // Act on new state.
      switch (state_.load(std::memory_order_acquire)) {
        case State::HasWork:
          // Got work to do! So do it, and then revert to 'Ready' state.
          ChangeState(State::Ready);
          break;
        case State::ExitAsSoonAsPossible:
          return;
        default:
          abort();
      }
    }
  }

  // The underlying thread.
  std::unique_ptr<std::thread> thread_;

  // The task to be worked on.
  Task* task_;

  // The condition variable and mutex guarding state changes.
  std::condition_variable state_cond_;
  std::mutex state_mutex_;

  // The state enum tells if we're currently working, waiting for work, etc.
  // Its concurrent accesses by the thread and main threads are guarded by
  // state_mutex_, and can thus use memory_order_relaxed. This still needs
  // to be a std::atomic because we use WaitForVariableChange.
  std::atomic<State> state_;

  // pointer to the master's thread BlockingCounter object, to notify the
  // master thread of when this thread switches to the 'Ready' state.
  BlockingCounter* const counter_to_decrement_when_ready_;
};

void ThreadPool::ExecuteImpl(int task_count, int stride, Task* tasks) {
  RUY_DCHECK_GE(task_count, 1);
  if (task_count > 1) {
    // Task #0 will be run on the current thread.
    CreateThreads(task_count - 1);
    counter_to_decrement_when_ready_.Reset(task_count - 1);
    for (int i = 1; i < task_count; i++) {
      auto task_address = reinterpret_cast<std::uintptr_t>(tasks) + i * stride;
      threads_[i - 1]->StartWork(reinterpret_cast<Task*>(task_address));
    }
  }

  // Execute task #0 immediately on the current thread.
  (tasks + 0)->Run();

  if (task_count > 1) {
    // Wait for the threads submitted above to finish.
    counter_to_decrement_when_ready_.Wait();
  }
}

// Ensures that the pool has at least the given count of threads.
// If any new thread has to be created, this function waits for it to
// be ready.
void ThreadPool::CreateThreads(int threads_count) {
  if (threads_.size() >= threads_count) {
    return;
  }
  counter_to_decrement_when_ready_.Reset(threads_count - threads_.size());
  while (threads_.size() < threads_count) {
    threads_.push_back(new Thread(&counter_to_decrement_when_ready_));
  }
  counter_to_decrement_when_ready_.Wait();
}

ThreadPool::~ThreadPool() {
  for (auto w : threads_) {
    delete w;
  }
}

}  // end namespace ruy
<commit_msg>Rewrite the handling of threads==1, so it's a little more readable, and gets compiled with -O3 in a way that puts this case at the start of the function instead of at the end, which for a mysterious reason results in more stable performance.<commit_after>/* Copyright 2019 Google LLC. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include "thread_pool.h"

#include <atomic>
#include <chrono>              // NOLINT(build/c++11)
#include <condition_variable>  // NOLINT(build/c++11)
#include <cstdint>
#include <cstdlib>
#include <memory>
#include <mutex>               // NOLINT(build/c++11)
#include <thread>              // NOLINT(build/c++11)

#include "check_macros.h"
#include "wait.h"

namespace ruy {

// A worker thread.
class Thread {
 public:
  enum class State {
    Startup,  // The initial state before the thread main loop runs.
    Ready,    // Is not working, has not yet received new work to do.
    HasWork,  // Has work to do.
    ExitAsSoonAsPossible  // Should exit at earliest convenience.
  };

  explicit Thread(BlockingCounter* counter_to_decrement_when_ready)
      : task_(nullptr),
        state_(State::Startup),
        counter_to_decrement_when_ready_(counter_to_decrement_when_ready) {
    thread_.reset(new std::thread(ThreadFunc, this));
  }

  ~Thread() {
    ChangeState(State::ExitAsSoonAsPossible);
    thread_->join();
  }

  // Changes State; may be called from either the worker thread
  // or the master thread; however, not all state transitions are legal,
  // which is guarded by assertions.
  //
  // The Task argument is to be used only with new_state==HasWork.
  // It specifies the Task being handed to this Thread.
  void ChangeState(State new_state, Task* task = nullptr) {
    state_mutex_.lock();
    State old_state = state_.load(std::memory_order_relaxed);
    RUY_DCHECK(old_state != new_state);
    switch (old_state) {
      case State::Startup:
        RUY_DCHECK(new_state == State::Ready);
        break;
      case State::Ready:
        RUY_DCHECK(new_state == State::HasWork ||
                   new_state == State::ExitAsSoonAsPossible);
        break;
      case State::HasWork:
        RUY_DCHECK(new_state == State::Ready ||
                   new_state == State::ExitAsSoonAsPossible);
        break;
      default:
        abort();
    }
    switch (new_state) {
      case State::Ready:
        if (task_) {
          // Doing work is part of reverting to 'ready' state.
          task_->Run();
          task_ = nullptr;
        }
        break;
      case State::HasWork:
        RUY_DCHECK(!task_);
        task_ = task;
        break;
      default:
        break;
    }
    state_.store(new_state, std::memory_order_relaxed);
    state_cond_.notify_all();
    state_mutex_.unlock();
    if (new_state == State::Ready) {
      counter_to_decrement_when_ready_->DecrementCount();
    }
  }

  static void ThreadFunc(Thread* arg) { arg->ThreadFuncImpl(); }

  // Called by the master thead to give this thread work to do.
  void StartWork(Task* task) { ChangeState(State::HasWork, task); }

 private:
  // Thread entry point.
  void ThreadFuncImpl() {
    ChangeState(State::Ready);

    // Thread main loop
    while (true) {
      // In the 'Ready' state, we have nothing to do but to wait until
      // we switch to another state.
      const auto& condition = [this]() {
        return state_.load(std::memory_order_acquire) != State::Ready;
      };
      WaitUntil(condition, &state_cond_, &state_mutex_);

      // Act on new state.
      switch (state_.load(std::memory_order_acquire)) {
        case State::HasWork:
          // Got work to do! So do it, and then revert to 'Ready' state.
          ChangeState(State::Ready);
          break;
        case State::ExitAsSoonAsPossible:
          return;
        default:
          abort();
      }
    }
  }

  // The underlying thread.
  std::unique_ptr<std::thread> thread_;

  // The task to be worked on.
  Task* task_;

  // The condition variable and mutex guarding state changes.
  std::condition_variable state_cond_;
  std::mutex state_mutex_;

  // The state enum tells if we're currently working, waiting for work, etc.
  // Its concurrent accesses by the thread and main threads are guarded by
  // state_mutex_, and can thus use memory_order_relaxed. This still needs
  // to be a std::atomic because we use WaitForVariableChange.
  std::atomic<State> state_;

  // pointer to the master's thread BlockingCounter object, to notify the
  // master thread of when this thread switches to the 'Ready' state.
  BlockingCounter* const counter_to_decrement_when_ready_;
};

void ThreadPool::ExecuteImpl(int task_count, int stride, Task* tasks) {
  RUY_DCHECK_GE(task_count, 1);

  // Case of 1 thread: just run the single task on the current thread.
  if (task_count == 1) {
    (tasks + 0)->Run();
    return;
  }

  // Task #0 will be run on the current thread.
  CreateThreads(task_count - 1);
  counter_to_decrement_when_ready_.Reset(task_count - 1);
  for (int i = 1; i < task_count; i++) {
    auto task_address = reinterpret_cast<std::uintptr_t>(tasks) + i * stride;
    threads_[i - 1]->StartWork(reinterpret_cast<Task*>(task_address));
  }

  // Execute task #0 immediately on the current thread.
  (tasks + 0)->Run();

  // Wait for the threads submitted above to finish.
  counter_to_decrement_when_ready_.Wait();
}

// Ensures that the pool has at least the given count of threads.
// If any new thread has to be created, this function waits for it to
// be ready.
void ThreadPool::CreateThreads(int threads_count) {
  if (threads_.size() >= threads_count) {
    return;
  }
  counter_to_decrement_when_ready_.Reset(threads_count - threads_.size());
  while (threads_.size() < threads_count) {
    threads_.push_back(new Thread(&counter_to_decrement_when_ready_));
  }
  counter_to_decrement_when_ready_.Wait();
}

ThreadPool::~ThreadPool() {
  for (auto w : threads_) {
    delete w;
  }
}

}  // end namespace ruy
<|endoftext|>


<commit_before>//
//  LuaFunctionWrapper.hpp
//  integral
//
//  Copyright (C) 2013, 2014, 2015, 2016  André Pereira Henriques
//  aphenriques (at) outlook (dot) com
//
//  This file is part of integral.
//
//  integral is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  integral is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with integral.  If not, see <http://www.gnu.org/licenses/>.
//

#ifndef integral_LuaFunctionWrapper_hpp
#define integral_LuaFunctionWrapper_hpp

#include <functional>
#include <utility>
#include <lua.hpp>
#include "exchanger.hpp"

namespace integral {
    namespace detail {
        // This class exists to make it possible to get exceptions thrown by luaFunction_ (see Exchanger<LuaFunctionWrapper>::push). For example, this is important to get exceptions thrown by exchanger::callConstructor when there are wrong parameters (exchanger::Exchange throws).
        // The function is managed by integral so that if an exception is thrown from it, it is translated to a Lua error
        // The first upvalue in the related lua_CFunction is always the userdata that holds LuaFunctionWrapper, so the remaining upvalues indexes are offset by 1.
        // Use getUpValueIndex or lua_upvalueindex(index + 1) to get an upvalue index.
        class LuaFunctionWrapper {
        public:
            // Gets adjusted upvalue index.
            // Exchanger<LuaFunctionWrapper>::push offsets the upvalues to insert the bound function userdata in the first position.
            static inline int getUpValueIndex(int index);

            // "luaFunction": lua_CFunction like function or functor.
            template<typename T>
            inline LuaFunctionWrapper(T &&luaFunction);

            // necessary because of the template constructor
            LuaFunctionWrapper(const LuaFunctionWrapper &) = default;
            LuaFunctionWrapper(LuaFunctionWrapper &) = default;
            LuaFunctionWrapper(LuaFunctionWrapper &&) = default;

            inline const std::function<int(lua_State *)> & getLuaFunction() const;

        private:
            std::function<int(lua_State *)> luaFunction_;
        };

        namespace exchanger {
            template<>
            class Exchanger<LuaFunctionWrapper> {
            public:
                static LuaFunctionWrapper get(lua_State *luaState, int index);

                // Attention: nUpValues > 0 distorts the premise that exchanger::push pushes a single element onto the lua stack because it removes nUpValues from the lua stack
                template<typename F>
                static void push(lua_State *luaState, F &&luaFunction, int nUpValues = 0);

            private:
                static const char * const kMetatableName_;
            };
        }

        //--

        inline int LuaFunctionWrapper::getUpValueIndex(int index) {
            return lua_upvalueindex(index + 1);
        }

        template<typename T>
        inline LuaFunctionWrapper::LuaFunctionWrapper(T &&luaFunction) : luaFunction_(std::forward<T>(luaFunction)) {}

        inline const std::function<int(lua_State *)> & LuaFunctionWrapper::getLuaFunction() const {
            return luaFunction_;
        }

        namespace exchanger {
            template<typename F>
            void Exchanger<LuaFunctionWrapper>::push(lua_State *luaState, F &&luaFunction, int nUpValues) {
                basic::pushUserData<LuaFunctionWrapper>(luaState, std::forward<F>(luaFunction));
                basic::pushClassMetatable<LuaFunctionWrapper>(luaState, kMetatableName_);
                lua_setmetatable(luaState, -2);
                if (nUpValues != 0) {
                    lua_insert(luaState, -1 - nUpValues);
                }
                lua_pushcclosure(luaState, [](lua_State *lambdaLuaState) -> int {
                    try {
                        const LuaFunctionWrapper *luaFunctionWrapper = static_cast<LuaFunctionWrapper *>(lua_compatibility::testudata(lambdaLuaState, lua_upvalueindex(1), kMetatableName_));
                        if (luaFunctionWrapper != nullptr) {
                            return luaFunctionWrapper->getLuaFunction()(lambdaLuaState);
                        } else {
                            throw exception::LogicException(__FILE__, __LINE__, __func__, "corrupted LuaFunctionWrapper");
                        }
                    } catch (const std::exception &exception) {
                        lua_pushstring(lambdaLuaState, (std::string("[integral] ") + exception.what()).c_str());
                    } catch (...) {
                        lua_pushstring(lambdaLuaState, message::gkUnknownExceptionMessage);
                    }
                    // error return outside catch scope so that the exception destructor can be called
                    return lua_error(lambdaLuaState);
                }, 1 + nUpValues);
            }
        }
    }
}

#endif
<commit_msg>removed message::gkUnknownExceptionMessage<commit_after>//
//  LuaFunctionWrapper.hpp
//  integral
//
//  Copyright (C) 2013, 2014, 2015, 2016  André Pereira Henriques
//  aphenriques (at) outlook (dot) com
//
//  This file is part of integral.
//
//  integral is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  integral is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with integral.  If not, see <http://www.gnu.org/licenses/>.
//

#ifndef integral_LuaFunctionWrapper_hpp
#define integral_LuaFunctionWrapper_hpp

#include <functional>
#include <utility>
#include <lua.hpp>
#include "exchanger.hpp"

namespace integral {
    namespace detail {
        // This class exists to make it possible to get exceptions thrown by luaFunction_ (see Exchanger<LuaFunctionWrapper>::push). For example, this is important to get exceptions thrown by exchanger::callConstructor when there are wrong parameters (exchanger::Exchange throws).
        // The function is managed by integral so that if an exception is thrown from it, it is translated to a Lua error
        // The first upvalue in the related lua_CFunction is always the userdata that holds LuaFunctionWrapper, so the remaining upvalues indexes are offset by 1.
        // Use getUpValueIndex or lua_upvalueindex(index + 1) to get an upvalue index.
        class LuaFunctionWrapper {
        public:
            // Gets adjusted upvalue index.
            // Exchanger<LuaFunctionWrapper>::push offsets the upvalues to insert the bound function userdata in the first position.
            static inline int getUpValueIndex(int index);

            // "luaFunction": lua_CFunction like function or functor.
            template<typename T>
            inline LuaFunctionWrapper(T &&luaFunction);

            // necessary because of the template constructor
            LuaFunctionWrapper(const LuaFunctionWrapper &) = default;
            LuaFunctionWrapper(LuaFunctionWrapper &) = default;
            LuaFunctionWrapper(LuaFunctionWrapper &&) = default;

            inline const std::function<int(lua_State *)> & getLuaFunction() const;

        private:
            std::function<int(lua_State *)> luaFunction_;
        };

        namespace exchanger {
            template<>
            class Exchanger<LuaFunctionWrapper> {
            public:
                static LuaFunctionWrapper get(lua_State *luaState, int index);

                // Attention: nUpValues > 0 distorts the premise that exchanger::push pushes a single element onto the lua stack because it removes nUpValues from the lua stack
                template<typename F>
                static void push(lua_State *luaState, F &&luaFunction, int nUpValues = 0);

            private:
                static const char * const kMetatableName_;
            };
        }

        //--

        inline int LuaFunctionWrapper::getUpValueIndex(int index) {
            return lua_upvalueindex(index + 1);
        }

        template<typename T>
        inline LuaFunctionWrapper::LuaFunctionWrapper(T &&luaFunction) : luaFunction_(std::forward<T>(luaFunction)) {}

        inline const std::function<int(lua_State *)> & LuaFunctionWrapper::getLuaFunction() const {
            return luaFunction_;
        }

        namespace exchanger {
            template<typename F>
            void Exchanger<LuaFunctionWrapper>::push(lua_State *luaState, F &&luaFunction, int nUpValues) {
                basic::pushUserData<LuaFunctionWrapper>(luaState, std::forward<F>(luaFunction));
                basic::pushClassMetatable<LuaFunctionWrapper>(luaState, kMetatableName_);
                lua_setmetatable(luaState, -2);
                if (nUpValues != 0) {
                    lua_insert(luaState, -1 - nUpValues);
                }
                lua_pushcclosure(luaState, [](lua_State *lambdaLuaState) -> int {
                    try {
                        const LuaFunctionWrapper *luaFunctionWrapper = static_cast<LuaFunctionWrapper *>(lua_compatibility::testudata(lambdaLuaState, lua_upvalueindex(1), kMetatableName_));
                        if (luaFunctionWrapper != nullptr) {
                            return luaFunctionWrapper->getLuaFunction()(lambdaLuaState);
                        } else {
                            throw exception::LogicException(__FILE__, __LINE__, __func__, "corrupted LuaFunctionWrapper");
                        }
                    } catch (const std::exception &exception) {
                        lua_pushstring(lambdaLuaState, (std::string("[integral] ") + exception.what()).c_str());
                    } catch (...) {
                        lua_pushstring(lambdaLuaState, "[integral] unknown exception thrown");
                    }
                    // error return outside catch scope so that the exception destructor can be called
                    return lua_error(lambdaLuaState);
                }, 1 + nUpValues);
            }
        }
    }
}

#endif
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: objmnctl.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: svesik $ $Date: 2004-04-21 13:18:08 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include <tools/list.hxx>
#ifndef _MENU_HXX //autogen
#include <vcl/menu.hxx>
#endif
#ifndef _PSEUDO_HXX //autogen
#include <so3/pseudo.hxx>
#endif
#ifndef _SFXSTRITEM_HXX //autogen
#include <svtools/stritem.hxx>
#endif
#ifndef GCC
#pragma hdrstop
#endif

#include "sfxsids.hrc"
#include "objmnctl.hxx"
#include "dispatch.hxx"
#include "viewsh.hxx"
#include "viewfrm.hxx"

// STATIC DATA -----------------------------------------------------------

SFX_IMPL_MENU_CONTROL(SfxObjectVerbsControl, SfxStringItem);

//--------------------------------------------------------------------

/*
    Ctor; setzt Select-Handler am Menu und traegt Menu
    in seinen Parent ein.
 */

SfxObjectVerbsControl::SfxObjectVerbsControl(USHORT nId, Menu &rMenu, SfxBindings &rBindings)
    : SfxMenuControl( nId, rBindings )
    , pMenu(new PopupMenu)
    , rParent(rMenu)
{
    rMenu.SetPopupMenu(nId, pMenu);
    pMenu->SetSelectHdl(LINK(this, SfxObjectVerbsControl, MenuSelect));
    FillMenu();
}

//--------------------------------------------------------------------

/*
    Fuellt das Menu mit den aktuellen Verben aus der ViewShell.
 */

void SfxObjectVerbsControl::FillMenu()
{
    pMenu->Clear();
    SfxViewShell *pView = GetBindings().GetDispatcher()->GetFrame()->GetViewShell();
    if (pView)
    {
        const SvVerbList *pList = pView->GetVerbs();
        if (pList)
        {
            USHORT nId = SID_VERB_START;
            for (USHORT n=0; n<pList->Count(); n++)
            {
                const SvVerb& rVerb = (*pList)[n];
                if (!rVerb.IsOnMenu())
                    continue;

                DBG_ASSERT(nId <= SID_VERB_END, "Zuviele Verben!");
                if (nId > SID_VERB_END)
                    break;

                pMenu->InsertItem(nId++, rVerb.GetName());
            }
        }
    }
    rParent.EnableItem( GetId(), (BOOL)pMenu->GetItemCount() );
}

//--------------------------------------------------------------------

/*
    Statusbenachrichtigung;
    fuellt gfs. das Menu mit den aktuellen Verben aus der ViewShell.
    der DocumentShell.
    Ist die Funktionalit"at disabled, wird der entsprechende
    Menueeintrag im Parentmenu disabled, andernfalls wird er enabled.
 */

void SfxObjectVerbsControl::StateChanged( USHORT nSID, SfxItemState eState,
                                          const SfxPoolItem* pState )
{
    rParent.EnableItem(GetId(), SFX_ITEM_AVAILABLE == eState );
    if ( SFX_ITEM_AVAILABLE == eState )
        FillMenu();
}

//--------------------------------------------------------------------

/*
    Select-Handler des Menus;
    das selektierte Verb mit ausgef"uhrt,
 */

IMPL_LINK_INLINE_START( SfxObjectVerbsControl, MenuSelect, Menu *, pMenu )
{
    const USHORT nId = pMenu->GetCurItemId();
    if( nId )
        GetBindings().Execute(nId);
    return 1;
}
IMPL_LINK_INLINE_END( SfxObjectVerbsControl, MenuSelect, Menu *, pMenu )

//--------------------------------------------------------------------

/*
    Dtor; gibt das Menu frei.
 */

SfxObjectVerbsControl::~SfxObjectVerbsControl()
{
    delete pMenu;
}

//--------------------------------------------------------------------

PopupMenu* SfxObjectVerbsControl::GetPopup() const
{
    return pMenu;
}

<commit_msg>INTEGRATION: CWS mav09 (1.1.1.1.424); FILE MERGED 2004/07/02 08:39:42 mba 1.1.1.1.424.5: #i27773#: some TODOs 2004/05/18 16:23:58 mav 1.1.1.1.424.4: #i27773# resolve resync problems 2004/04/29 21:24:52 mav 1.1.1.1.424.3: RESYNC: (1.1.1.1-1.2); FILE MERGED 2004/04/29 10:57:24 mba 1.1.1.1.424.2: #i27773#: remove so3 2004/04/14 11:48:38 mba 1.1.1.1.424.1: #i27773#: remove so3<commit_after>/*************************************************************************
 *
 *  $RCSfile: objmnctl.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: kz $ $Date: 2004-10-04 21:00:19 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _COM_SUN_STAR_EMBED_VERBDESCRIPTOR_HPP_
#include <com/sun/star/embed/VerbDescriptor.hpp>
#endif
#ifndef _COM_SUN_STAR_EMBED_VERBATTRIBUTES_HPP_
#include <com/sun/star/embed/VerbAttributes.hpp>
#endif

#include <tools/list.hxx>
#ifndef _MENU_HXX //autogen
#include <vcl/menu.hxx>
#endif
#ifndef _SXSTRITEM_HXX //autogen
#include <svtools/stritem.hxx>
#endif
#ifndef GCC
#pragma hdrstop
#endif

#include "sfxsids.hrc"
#include "objmnctl.hxx"
#include "dispatch.hxx"
#include "viewsh.hxx"
#include "viewfrm.hxx"
#include "objsh.hxx"

// STATIC DATA -----------------------------------------------------------

SFX_IMPL_MENU_CONTROL(SfxObjectVerbsControl, SfxStringItem);

using namespace com::sun::star;
//--------------------------------------------------------------------

/*
    Ctor; setzt Select-Handler am Menu und traegt Menu
    in seinen Parent ein.
 */

SfxObjectVerbsControl::SfxObjectVerbsControl(USHORT nId, Menu &rMenu, SfxBindings &rBindings)
    : SfxMenuControl( nId, rBindings )
    , pMenu(new PopupMenu)
    , rParent(rMenu)
{
    rMenu.SetPopupMenu(nId, pMenu);
    pMenu->SetSelectHdl(LINK(this, SfxObjectVerbsControl, MenuSelect));
    FillMenu();
}

//--------------------------------------------------------------------

/*
    Fuellt das Menu mit den aktuellen Verben aus der ViewShell.
 */

void SfxObjectVerbsControl::FillMenu()
{
    pMenu->Clear();
    SfxViewShell *pView = GetBindings().GetDispatcher()->GetFrame()->GetViewShell();
    if (pView)
    {
        SfxObjectShell* pDoc = pView->GetObjectShell();
        const com::sun::star::uno::Sequence < com::sun::star::embed::VerbDescriptor >& aVerbs =  pView->GetVerbs();
        if ( aVerbs.getLength() )
        {
            USHORT nId = SID_VERB_START;
            for (USHORT n=0; n<aVerbs.getLength(); n++)
            {
                // check for ReadOnly verbs
                if ( pDoc->IsReadOnly() && !(aVerbs[n].VerbAttributes & embed::VerbAttributes::MS_VERBATTR_NEVERDIRTIES) )
                    continue;

                // check for verbs that shouldn't appear in the menu
                if ( !(aVerbs[n].VerbAttributes & embed::VerbAttributes::MS_VERBATTR_ONCONTAINERMENU) )
                    continue;

                DBG_ASSERT(nId <= SID_VERB_END, "Zuviele Verben!");
                if (nId > SID_VERB_END)
                    break;

                pMenu->InsertItem(nId++, aVerbs[n].VerbName);
            }
        }
    }

    rParent.EnableItem( GetId(), (BOOL)pMenu->GetItemCount() );
}

//--------------------------------------------------------------------

/*
    Statusbenachrichtigung;
    fuellt gfs. das Menu mit den aktuellen Verben aus der ViewShell.
    der DocumentShell.
    Ist die Funktionalit"at disabled, wird der entsprechende
    Menueeintrag im Parentmenu disabled, andernfalls wird er enabled.
 */

void SfxObjectVerbsControl::StateChanged( USHORT nSID, SfxItemState eState,
                                          const SfxPoolItem* pState )
{
    rParent.EnableItem(GetId(), SFX_ITEM_AVAILABLE == eState );
    if ( SFX_ITEM_AVAILABLE == eState )
        FillMenu();
}

//--------------------------------------------------------------------

/*
    Select-Handler des Menus;
    das selektierte Verb mit ausgef"uhrt,
 */

IMPL_LINK_INLINE_START( SfxObjectVerbsControl, MenuSelect, Menu *, pMenu )
{
    const USHORT nId = pMenu->GetCurItemId();
    if( nId )
        GetBindings().Execute(nId);
    return 1;
}
IMPL_LINK_INLINE_END( SfxObjectVerbsControl, MenuSelect, Menu *, pMenu )

//--------------------------------------------------------------------

/*
    Dtor; gibt das Menu frei.
 */

SfxObjectVerbsControl::~SfxObjectVerbsControl()
{
    delete pMenu;
}

//--------------------------------------------------------------------

PopupMenu* SfxObjectVerbsControl::GetPopup() const
{
    return pMenu;
}

<|endoftext|>


<commit_before>/** \file    update_ixtheo_notations.cc
 *  \brief   Move the ixTheo classification notations from local data into field 652a.
 *  \author  Dr. Johannes Ruscheinski
 */

/*
    Copyright (C) 2015,2017-2019 Library of the University of Tübingen

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as
    published by the Free Software Foundation, either version 3 of the
    License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <iostream>
#include <unordered_map>
#include <cctype>
#include <cstdlib>
#include "MARC.h"
#include "StringUtil.h"
#include "util.h"

void Usage() {
    std::cerr << "Usage: " << ::progname << " marc_input marc_output code_to_description_map\n";
    std::exit(EXIT_FAILURE);
}

void LoadCodeToDescriptionMap(File * const code_to_description_map_file,
                              std::unordered_map<std::string, std::string> * const code_to_description_map)
{
    unsigned line_no(0);
    while (not code_to_description_map_file->eof()) {
        const std::string line(code_to_description_map_file->getline());
        ++line_no;
        if (line.length() < 4) // Need at least a 2 character code, a comma and some text.
            continue;

        const size_t comma_pos(line.find(','));
        if (comma_pos == std::string::npos)
            logger->error("in LoadCodeToDescriptionMap: malformed line " + std::to_string(line_no) + " in \""
                          + code_to_description_map_file->getPath() + "\"! (1)");

        const std::string code(line.substr(0, comma_pos));
        if (code.length() != 2 and code.length() != 3)
            logger->error("in LoadCodeToDescriptionMap: malformed line " + std::to_string(line_no) + " in \""
                          + code_to_description_map_file->getPath() + "\"! (2)");

        (*code_to_description_map)[code] = line.substr(comma_pos + 1);
    }

    std::cerr << "Found " << code_to_description_map->size() << " code to description mappings.\n";
}

bool LocalBlockIsFromIxTheoTheologians(const MARC::Record::const_iterator &local_block_start, const MARC::Record &record) {
    for (const auto &_852_local_field : record.findFieldsInLocalBlock("852", local_block_start, /*indicator1*/' ', /*indicator2*/' ')) {
        const MARC::Subfields subfields(_852_local_field.getSubfields());
        if (subfields.hasSubfieldWithValue('a', "Tü 135") or subfields.hasSubfieldWithValue('a', "Tü 135/1"))
            return true;
    }

    return false;
}

unsigned ExtractIxTheoNotations(const MARC::Record::const_iterator &local_block_start, const MARC::Record &record,
                                const std::unordered_map<std::string, std::string> &code_to_description_map,
                                std::set<std::string> * const ixtheo_notations_set)
{
    for (const auto &_936_local_field : record.findFieldsInLocalBlock("936", local_block_start, /*indicator1*/'l', /*indicator2*/'n')) {
        const MARC::Subfields subfields(_936_local_field.getSubfields());
        const std::string ixtheo_notation_candidate(subfields.getFirstSubfieldWithCode('a'));
        if (code_to_description_map.find(ixtheo_notation_candidate) != code_to_description_map.end())
            ixtheo_notations_set->emplace(ixtheo_notation_candidate);
    }
    return ixtheo_notations_set->size();
}

void ProcessRecords(MARC::Reader * const marc_reader, MARC::Writer * const marc_writer,
                    const std::unordered_map<std::string, std::string> &code_to_description_map)
{
    unsigned count(0), ixtheo_notation_count(0), records_with_ixtheo_notations(0);
    while (MARC::Record record = marc_reader->read()) {
        ++count;

        std::set<std::string> ixtheo_notations_set;
        std::string ixtheo_notations_list; // Colon-separated list of ixTheo notations.
        for (const auto &local_block_start_iter : record.findStartOfAllLocalDataBlocks()) {
            if (not LocalBlockIsFromIxTheoTheologians(local_block_start_iter, record))
                continue;

            ExtractIxTheoNotations(local_block_start_iter, record, code_to_description_map,
                                   &ixtheo_notations_set);
        }

        if (not ixtheo_notations_set.empty()) { // Insert a new 652 field w/ a $a subfield.
            ixtheo_notation_count += StringUtil::Join(ixtheo_notations_set, ':', &ixtheo_notations_list);
            ++records_with_ixtheo_notations;
            record.insertField("652", { { 'a', ixtheo_notations_list } });
        }
        marc_writer->write(record);
    }

    std::cout << ::progname << ": Read " << count << " records.\n";
    std::cout << ::progname << ": " << records_with_ixtheo_notations << " records had ixTheo notations.\n";
    std::cout << ::progname << ": Found " << ixtheo_notation_count << " ixTheo notations overall.\n";
}

int Main(int argc, char **argv) {
    ::progname = argv[0];

    if (argc != 4)
        Usage();

    std::unique_ptr<MARC::Reader> marc_reader(MARC::Reader::Factory(argv[1], MARC::FileType::BINARY));
    std::unique_ptr<MARC::Writer> marc_writer(MARC::Writer::Factory(argv[2], MARC::FileType::BINARY));

    const std::string code_to_description_map_filename(argv[3]);
    File code_to_description_map_file(code_to_description_map_filename, "r");
    if (not code_to_description_map_file)
        logger->error("can't open \"" + code_to_description_map_filename + "\" for reading!");

    std::unordered_map<std::string, std::string> code_to_description_map;
    LoadCodeToDescriptionMap(&code_to_description_map_file, &code_to_description_map);
    ProcessRecords(marc_reader.get(), marc_writer.get(), code_to_description_map);

    return EXIT_SUCCESS;
}
<commit_msg>update_ixtheo_notations: also check for "DE-Tue135" in LOK 852u, see ubtue/tuefind#1042<commit_after>/** \file    update_ixtheo_notations.cc
 *  \brief   Move the ixTheo classification notations from local data into field 652a.
 *  \author  Dr. Johannes Ruscheinski
 */

/*
    Copyright (C) 2015,2017-2019 Library of the University of Tübingen

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as
    published by the Free Software Foundation, either version 3 of the
    License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <iostream>
#include <unordered_map>
#include <cctype>
#include <cstdlib>
#include "MARC.h"
#include "StringUtil.h"
#include "util.h"

[[noreturn]] void Usage() {
    ::Usage("marc_input marc_output code_to_description_map");
}

void LoadCodeToDescriptionMap(File * const code_to_description_map_file,
                              std::unordered_map<std::string, std::string> * const code_to_description_map)
{
    unsigned line_no(0);
    while (not code_to_description_map_file->eof()) {
        const std::string line(code_to_description_map_file->getline());
        ++line_no;
        if (line.length() < 4) // Need at least a 2 character code, a comma and some text.
            continue;

        const size_t comma_pos(line.find(','));
        if (comma_pos == std::string::npos)
            LOG_ERROR("in LoadCodeToDescriptionMap: malformed line " + std::to_string(line_no) + " in \""
                      + code_to_description_map_file->getPath() + "\"! (1)");

        const std::string code(line.substr(0, comma_pos));
        if (code.length() != 2 and code.length() != 3)
            LOG_ERROR("in LoadCodeToDescriptionMap: malformed line " + std::to_string(line_no) + " in \""
                      + code_to_description_map_file->getPath() + "\"! (2)");

        (*code_to_description_map)[code] = line.substr(comma_pos + 1);
    }

    LOG_INFO("Found " + std::to_string(code_to_description_map->size()) + " code to description mappings.");
}

bool LocalBlockIsFromIxTheoTheologians(const MARC::Record::const_iterator &local_block_start, const MARC::Record &record) {
    for (const auto &_852_local_field : record.findFieldsInLocalBlock("852", local_block_start, /*indicator1*/' ', /*indicator2*/' ')) {
        const MARC::Subfields subfields(_852_local_field.getSubfields());
        if (subfields.hasSubfieldWithValue('a', "Tü 135") or subfields.hasSubfieldWithValue('a', "Tü 135/1")
            or subfields.hasSubfieldWithValue('a', "DE-Tue135"))
            return true;
    }

    return false;
}

unsigned ExtractIxTheoNotations(const MARC::Record::const_iterator &local_block_start, const MARC::Record &record,
                                const std::unordered_map<std::string, std::string> &code_to_description_map,
                                std::set<std::string> * const ixtheo_notations_set)
{
    for (const auto &_936_local_field : record.findFieldsInLocalBlock("936", local_block_start, /*indicator1*/'l', /*indicator2*/'n')) {
        const MARC::Subfields subfields(_936_local_field.getSubfields());
        const std::string ixtheo_notation_candidate(subfields.getFirstSubfieldWithCode('a'));
        if (code_to_description_map.find(ixtheo_notation_candidate) != code_to_description_map.end())
            ixtheo_notations_set->emplace(ixtheo_notation_candidate);
    }
    return ixtheo_notations_set->size();
}

void ProcessRecords(MARC::Reader * const marc_reader, MARC::Writer * const marc_writer,
                    const std::unordered_map<std::string, std::string> &code_to_description_map)
{
    unsigned count(0), ixtheo_notation_count(0), records_with_ixtheo_notations(0);
    while (MARC::Record record = marc_reader->read()) {
        ++count;

        std::set<std::string> ixtheo_notations_set;
        std::string ixtheo_notations_list; // Colon-separated list of ixTheo notations.
        for (const auto &local_block_start_iter : record.findStartOfAllLocalDataBlocks()) {
            if (not LocalBlockIsFromIxTheoTheologians(local_block_start_iter, record))
                continue;

            ExtractIxTheoNotations(local_block_start_iter, record, code_to_description_map,
                                   &ixtheo_notations_set);
        }

        if (not ixtheo_notations_set.empty()) { // Insert a new 652 field w/ a $a subfield.
            ixtheo_notation_count += StringUtil::Join(ixtheo_notations_set, ':', &ixtheo_notations_list);
            ++records_with_ixtheo_notations;
            record.insertField("652", { { 'a', ixtheo_notations_list } });
        }
        marc_writer->write(record);
    }

    LOG_INFO("Read " + std::to_string(count) + " records.");
    LOG_INFO(std::to_string(records_with_ixtheo_notations) + " records had ixTheo notations.");
    LOG_INFO("Found " + std::to_string(ixtheo_notation_count) + " ixTheo notations overall.");
}

int Main(int argc, char **argv) {
    if (argc != 4)
        Usage();

    std::unique_ptr<MARC::Reader> marc_reader(MARC::Reader::Factory(argv[1], MARC::FileType::BINARY));
    std::unique_ptr<MARC::Writer> marc_writer(MARC::Writer::Factory(argv[2], MARC::FileType::BINARY));

    const std::string code_to_description_map_filename(argv[3]);
    File code_to_description_map_file(code_to_description_map_filename, "r");
    if (not code_to_description_map_file)
        LOG_ERROR("can't open \"" + code_to_description_map_filename + "\" for reading!");

    std::unordered_map<std::string, std::string> code_to_description_map;
    LoadCodeToDescriptionMap(&code_to_description_map_file, &code_to_description_map);
    ProcessRecords(marc_reader.get(), marc_writer.get(), code_to_description_map);

    return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/*
manager.cpp

४祭  ᪮쪨 file panels, viewers, editors

*/

/* Revision: 1.03 13.07.2000 $ */

/*
Modify:
  13.07.2000 SVS
    !  ४樨  ᯮ짮 new/delete/realloc
  11.07.2000 SVS
    !    樨  BC & VC
  28.06.2000 tran
    - NT Console resize
      add class member ActiveModal
  25.06.2000 SVS
    ! ⮢ Master Copy
    ! 뤥  ⢥ ᠬ⥫쭮
*/

#include "headers.hpp"
#pragma hdrstop

/* $ 30.06.2000 IS
   ⠭
*/
#include "internalheaders.hpp"
/* IS $ */

Manager::Manager()
{
  ModalList=NULL;
  ModalCount=ModalPos=0;
  UpdateRequired=FALSE;
  *NextName=0;
  /* $ 28.06.2000 tran
     clear it */
  ActiveModal=0;
  /* tran $ */
}

void Manager::CloseAll()
{
  int I;
  for (I=0;I<ModalCount;I++)
  {
    Modal *CurModal=ModalList[I];
    CurModal->ClearDone();
    CurModal->SetEnableSwitch(FALSE);
    CurModal->Show();
    CurModal->ProcessKey(KEY_ESC);
    if (!CurModal->Done())
    {
      CurModal->ShowConsoleTitle();
      CurModal->Process();
    }
    delete CurModal;
  }
  /* $ 13.07.2000 SVS
      뫮 "delete ModalList;",  । ᨢ 뫮
      १ realloc...
  */
  free(ModalList);
  /* SVS $ */
  ModalList=NULL;
  ModalCount=ModalPos=0;
}

BOOL Manager::IsAnyModalModified(int Activate)
{
  for (int I=0;I<ModalCount;I++)
    if (ModalList[I]->IsFileModified())
    {
      if (Activate)
      {
        ModalPos=I;
        NextModal(0);
      }
      return(TRUE);
    }
  return(FALSE);
}

void Manager::AddModal(Modal *NewModal)
{
  int ExitCode=NewModal->GetExitCode();
  if (ExitCode<=0)
  {
    delete NewModal;
    CtrlObject->ActivePanel->SetTitle();
    CtrlObject->LeftPanel->Redraw();
    ActivateNextWindow();
    ModalPos=ModalCount;
    return;
  }
  ModalList=(Modal **)realloc(ModalList,sizeof(*ModalList)*(ModalCount+1));
  ModalPos=ModalCount;
  ModalList[ModalCount]=NewModal;
  ModalCount++;
  if (ExitCode==2)
    SelectModal();
  else
    if (ExitCode==3)
    {
      if (--ModalPos<0)
        ModalPos=ModalCount;
    }
    else
      ModalPos++;
  NewModal->Hide();
  NextModal(0);
}

void Manager::NextModal(int Increment)
{
  if (ModalCount>0)
  {
    ModalPos+=Increment;
    if (ModalPos<0)
      ModalPos=ModalCount-1;
  }
  while (ModalCount>0)
  {
    if (ModalPos==ModalCount)
      break;
    if (ModalPos>ModalCount)
      ModalPos=0;
    Modal *CurModal=ModalList[ModalPos];
    CurModal->ClearDone();
    CurModal->ShowConsoleTitle();
    CurModal->Process();

    char Type[200],Name[NM];
    if (CurModal->GetTypeAndName(Type,Name)==MODALTYPE_EDITOR)
      UpdateRequired=TRUE;

    int ExitCode=CurModal->GetExitCode();
    if (ExitCode<=0)
    {
      delete CurModal;
      for (int I=ModalPos+1;I<ModalCount;I++)
        ModalList[I-1]=ModalList[I];
      ModalCount--;
      if (*NextName)
      {
        ActivateNextWindow();
        return;
      }
    }
    else
    {
      if (ExitCode==2)
        SelectModal();
      else
        if (ExitCode==3)
        {
          if (--ModalPos<0)
            ModalPos=ModalCount;
        }
        else
          ModalPos++;
      CurModal->Hide();
    }
  }
  CtrlObject->ActivePanel->SetTitle();
  if (UpdateRequired)
  {
    CtrlObject->LeftPanel->Update(UPDATE_KEEP_SELECTION|UPDATE_SECONDARY);
    CtrlObject->RightPanel->Update(UPDATE_KEEP_SELECTION|UPDATE_SECONDARY);
    UpdateRequired=TRUE;
  }
  CtrlObject->LeftPanel->Redraw();
  CtrlObject->RightPanel->Redraw();
  CtrlObject->CmdLine.Redraw();
  CtrlObject->MainKeyBar.Redraw();
}

void Manager::SelectModal()
{
  int ExitCode;
  {
    struct MenuItem ModalMenuItem;
    ModalMenuItem.Checked=ModalMenuItem.Separator=*ModalMenuItem.UserData=ModalMenuItem.UserDataSize=0;
    VMenu ModalMenu(MSG(MScreensTitle),NULL,0,ScrY-4);
    ModalMenu.SetHelp("ScrSwitch");
    ModalMenu.SetFlags(MENU_WRAPMODE);
    ModalMenu.SetPosition(-1,-1,0,0);

    sprintf(ModalMenuItem.Name,"&0. %-30s",MSG(MScreensPanels));
    ModalMenuItem.Selected=(ModalPos==ModalCount);
    ModalMenu.AddItem(&ModalMenuItem);

    for (int I=0;I<ModalCount;I++)
    {
      char Type[200],Name[NM],NumText[100];
      ModalList[I]->GetTypeAndName(Type,Name);
      if (I<9)
        sprintf(NumText,"&%d. ",I+1);
      else
        strcpy(NumText,"&   ");
      TruncStr(Name,30);
      sprintf(ModalMenuItem.Name,"%s%-30s %s",NumText,Type,PointToName(Name));
      ModalMenuItem.Selected=(I==ModalPos);
      ModalMenu.AddItem(&ModalMenuItem);
    }
    ModalMenu.Process();
    ExitCode=ModalMenu.GetExitCode();
  }
  if (ExitCode>=0)
    if (ExitCode==0)
      ModalPos=ModalCount;
    else
      ModalPos=ExitCode-1;
}

void Manager::GetModalTypesCount(int &Viewers,int &Editors)
{
  Viewers=Editors=0;
  for (int I=0;I<ModalCount;I++)
  {
    char Type[200],Name[NM];
    switch(ModalList[I]->GetTypeAndName(Type,Name))
    {
      case MODALTYPE_VIEWER:
        Viewers++;
        break;
      case MODALTYPE_EDITOR:
        Editors++;
        break;
    }
  }
}

void Manager::SetModalPos(int NewPos)
{
  ModalPos=NewPos;
}

int Manager::FindModalByFile(int ModalType,char *FileName)
{
  for (int I=0;I<ModalCount;I++)
  {
    char Type[200],Name[NM];
    if (ModalList[I]->GetTypeAndName(Type,Name)==ModalType)
      if (LocalStricmp(Name,FileName)==0)
        return(I);
  }
  return(-1);
}

void Manager::ShowBackground()
{
  if (!RegVer)
  {
    Message(MSG_WARNING,1,MSG(MWarning),MSG(MRegOnly),MSG(MOk));
    return;
  }

  SaveScreen SaveScr;
  int I;
  for (I=0;I<ModalCount;I++)
  {
    Modal *CurModal=ModalList[I];
    CurModal->Hide();
  }
  {
    RedrawDesktop Redraw;
    CtrlObject->CmdLine.Hide();
    SetCursorType(FALSE,10);
    WaitKey();
    CtrlObject->CmdLine.Show();
  }
  for (I=0;I<ModalCount;I++)
  {
    Modal *CurModal=ModalList[I];
    CurModal->SavePrevScreen();
  }
}

void Manager::SetNextWindow(int Viewer,char *Name,long Pos)
{
  NextViewer=Viewer;
  strcpy(NextName,Name);
  NextPos=Pos;
}

void Manager::ActivateNextWindow()
{
  if (*NextName)
  {
    Modal *NewModal;
    char NewName[NM];
    strcpy(NewName,NextName);
    *NextName=0;
    if (NextViewer)
      NewModal=new FileViewer(NewName,TRUE,FALSE,FALSE,NextPos);
    else
      NewModal=new FileEditor(NewName,FALSE,TRUE,-2,NextPos,FALSE);
    AddModal(NewModal);
  }
}
<commit_msg>FAR patch 00094.manager.cpp Дата              : 28.07.2000 Сделал            : andrey tretjakov Описание          : косметика при выводе списка окон                      измененные файлы в редакторе маркируются "*" Измененные файлы  : manager.cpp Состав            : manager.cpp.at.txt manager.cpp.diff Основан на патче  : 90 Дополнение        : <commit_after>/*
manager.cpp

४祭  ᪮쪨 file panels, viewers, editors

*/

/* Revision: 1.04 28.07.2000 $ */

/*
Modify:
  28.07.2000 tran 1.04
    + ᬥ⨪  뢮 ᯨ᪠  -
       䠩  । ન "*"
  13.07.2000 SVS
    !  ४樨  ᯮ짮 new/delete/realloc
  11.07.2000 SVS
    !    樨  BC & VC
  28.06.2000 tran
    - NT Console resize
      add class member ActiveModal
  25.06.2000 SVS
    ! ⮢ Master Copy
    ! 뤥  ⢥ ᠬ⥫쭮
*/

#include "headers.hpp"
#pragma hdrstop

/* $ 30.06.2000 IS
   ⠭
*/
#include "internalheaders.hpp"
/* IS $ */

Manager::Manager()
{
  ModalList=NULL;
  ModalCount=ModalPos=0;
  UpdateRequired=FALSE;
  *NextName=0;
  /* $ 28.06.2000 tran
     clear it */
  ActiveModal=0;
  /* tran $ */
}

void Manager::CloseAll()
{
  int I;
  for (I=0;I<ModalCount;I++)
  {
    Modal *CurModal=ModalList[I];
    CurModal->ClearDone();
    CurModal->SetEnableSwitch(FALSE);
    CurModal->Show();
    CurModal->ProcessKey(KEY_ESC);
    if (!CurModal->Done())
    {
      CurModal->ShowConsoleTitle();
      CurModal->Process();
    }
    delete CurModal;
  }
  /* $ 13.07.2000 SVS
      뫮 "delete ModalList;",  । ᨢ 뫮
      १ realloc...
  */
  free(ModalList);
  /* SVS $ */
  ModalList=NULL;
  ModalCount=ModalPos=0;
}

BOOL Manager::IsAnyModalModified(int Activate)
{
  for (int I=0;I<ModalCount;I++)
    if (ModalList[I]->IsFileModified())
    {
      if (Activate)
      {
        ModalPos=I;
        NextModal(0);
      }
      return(TRUE);
    }
  return(FALSE);
}

void Manager::AddModal(Modal *NewModal)
{
  int ExitCode=NewModal->GetExitCode();
  if (ExitCode<=0)
  {
    delete NewModal;
    CtrlObject->ActivePanel->SetTitle();
    CtrlObject->LeftPanel->Redraw();
    ActivateNextWindow();
    ModalPos=ModalCount;
    return;
  }
  ModalList=(Modal **)realloc(ModalList,sizeof(*ModalList)*(ModalCount+1));
  ModalPos=ModalCount;
  ModalList[ModalCount]=NewModal;
  ModalCount++;
  if (ExitCode==2)
    SelectModal();
  else
    if (ExitCode==3)
    {
      if (--ModalPos<0)
        ModalPos=ModalCount;
    }
    else
      ModalPos++;
  NewModal->Hide();
  NextModal(0);
}

void Manager::NextModal(int Increment)
{
  if (ModalCount>0)
  {
    ModalPos+=Increment;
    if (ModalPos<0)
      ModalPos=ModalCount-1;
  }
  while (ModalCount>0)
  {
    if (ModalPos==ModalCount)
      break;
    if (ModalPos>ModalCount)
      ModalPos=0;
    Modal *CurModal=ModalList[ModalPos];
    CurModal->ClearDone();
    CurModal->ShowConsoleTitle();
    CurModal->Process();

    char Type[200],Name[NM];
    if (CurModal->GetTypeAndName(Type,Name)==MODALTYPE_EDITOR)
      UpdateRequired=TRUE;

    int ExitCode=CurModal->GetExitCode();
    if (ExitCode<=0)
    {
      delete CurModal;
      for (int I=ModalPos+1;I<ModalCount;I++)
        ModalList[I-1]=ModalList[I];
      ModalCount--;
      if (*NextName)
      {
        ActivateNextWindow();
        return;
      }
    }
    else
    {
      if (ExitCode==2)
        SelectModal();
      else
        if (ExitCode==3)
        {
          if (--ModalPos<0)
            ModalPos=ModalCount;
        }
        else
          ModalPos++;
      CurModal->Hide();
    }
  }
  CtrlObject->ActivePanel->SetTitle();
  if (UpdateRequired)
  {
    CtrlObject->LeftPanel->Update(UPDATE_KEEP_SELECTION|UPDATE_SECONDARY);
    CtrlObject->RightPanel->Update(UPDATE_KEEP_SELECTION|UPDATE_SECONDARY);
    UpdateRequired=TRUE;
  }
  CtrlObject->LeftPanel->Redraw();
  CtrlObject->RightPanel->Redraw();
  CtrlObject->CmdLine.Redraw();
  CtrlObject->MainKeyBar.Redraw();
}

void Manager::SelectModal()
{
  int ExitCode;
  {
    struct MenuItem ModalMenuItem;
    ModalMenuItem.Checked=ModalMenuItem.Separator=*ModalMenuItem.UserData=ModalMenuItem.UserDataSize=0;
    VMenu ModalMenu(MSG(MScreensTitle),NULL,0,ScrY-4);
    ModalMenu.SetHelp("ScrSwitch");
    ModalMenu.SetFlags(MENU_WRAPMODE);
    ModalMenu.SetPosition(-1,-1,0,0);

    sprintf(ModalMenuItem.Name,"&0. %-30s",MSG(MScreensPanels));
    ModalMenuItem.Selected=(ModalPos==ModalCount);
    ModalMenu.AddItem(&ModalMenuItem);

    for (int I=0;I<ModalCount;I++)
    {
      char Type[200],Name[NM],NumText[100];
      ModalList[I]->GetTypeAndName(Type,Name);
      if (I<9)
        sprintf(NumText,"&%d. ",I+1);
      else
        strcpy(NumText,"&   ");
      /* $ 28.07.2000 tran
         䠩 ᥪ  ਭ ࠭ */
      TruncStr(Name,ScrX-40);
      /*   "*" ᫨ 䠩  */
      sprintf(ModalMenuItem.Name,"%s%-20s %c %s",NumText,Type,(ModalList[I]->IsFileModified()?'*':' '),Name);
      /* tran 28.07.2000 $ */
      ModalMenuItem.Selected=(I==ModalPos);
      ModalMenu.AddItem(&ModalMenuItem);
    }
    ModalMenu.Process();
    ExitCode=ModalMenu.GetExitCode();
  }
  if (ExitCode>=0)
    if (ExitCode==0)
      ModalPos=ModalCount;
    else
      ModalPos=ExitCode-1;
}

void Manager::GetModalTypesCount(int &Viewers,int &Editors)
{
  Viewers=Editors=0;
  for (int I=0;I<ModalCount;I++)
  {
    char Type[200],Name[NM];
    switch(ModalList[I]->GetTypeAndName(Type,Name))
    {
      case MODALTYPE_VIEWER:
        Viewers++;
        break;
      case MODALTYPE_EDITOR:
        Editors++;
        break;
    }
  }
}

void Manager::SetModalPos(int NewPos)
{
  ModalPos=NewPos;
}

int Manager::FindModalByFile(int ModalType,char *FileName)
{
  for (int I=0;I<ModalCount;I++)
  {
    char Type[200],Name[NM];
    if (ModalList[I]->GetTypeAndName(Type,Name)==ModalType)
      if (LocalStricmp(Name,FileName)==0)
        return(I);
  }
  return(-1);
}

void Manager::ShowBackground()
{
  if (!RegVer)
  {
    Message(MSG_WARNING,1,MSG(MWarning),MSG(MRegOnly),MSG(MOk));
    return;
  }

  SaveScreen SaveScr;
  int I;
  for (I=0;I<ModalCount;I++)
  {
    Modal *CurModal=ModalList[I];
    CurModal->Hide();
  }
  {
    RedrawDesktop Redraw;
    CtrlObject->CmdLine.Hide();
    SetCursorType(FALSE,10);
    WaitKey();
    CtrlObject->CmdLine.Show();
  }
  for (I=0;I<ModalCount;I++)
  {
    Modal *CurModal=ModalList[I];
    CurModal->SavePrevScreen();
  }
}

void Manager::SetNextWindow(int Viewer,char *Name,long Pos)
{
  NextViewer=Viewer;
  strcpy(NextName,Name);
  NextPos=Pos;
}

void Manager::ActivateNextWindow()
{
  if (*NextName)
  {
    Modal *NewModal;
    char NewName[NM];
    strcpy(NewName,NextName);
    *NextName=0;
    if (NextViewer)
      NewModal=new FileViewer(NewName,TRUE,FALSE,FALSE,NextPos);
    else
      NewModal=new FileEditor(NewName,FALSE,TRUE,-2,NextPos,FALSE);
    AddModal(NewModal);
  }
}
<|endoftext|>


<commit_before>// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "local_rpc_monitor_map.h"
#include "sbenv.h"
#include <vespa/fnet/frt/supervisor.h>
#include <vespa/log/log.h>
LOG_SETUP(".slobrok.server.local_rpc_monitor_map");

namespace slobrok {

#pragma GCC diagnostic ignored "-Winline"

void LocalRpcMonitorMap::DelayedTasks::PerformTask() {
    {
        std::vector<MUP> deleteAfterSwap;
        std::swap(deleteAfterSwap, _deleteList);
    }
    std::vector<Event> todo;
    std::swap(todo, _queue);
    for (const auto & entry : todo) {
        switch (entry.type) {
        case EventType::ADD:
            _target.doAdd(entry.mapping);
            break;
        case EventType::REMOVE:
            _target.doRemove(entry.mapping);
            break;
        default:
            abort();
        }
    }
}

LocalRpcMonitorMap::LocalRpcMonitorMap(FRT_Supervisor &supervisor)
  : _delayedTasks(supervisor.GetScheduler(), *this),
    _map(),
    _dispatcher(),
    _history(),
    _supervisor(supervisor),
    _subscription(MapSubscription::subscribe(_dispatcher, _history))
{
}

LocalRpcMonitorMap::~LocalRpcMonitorMap() = default;

LocalRpcMonitorMap::PerService *
LocalRpcMonitorMap::lookup(ManagedRpcServer *rpcsrv) {
    auto iter = _map.find(rpcsrv->getName());
    if (iter == _map.end()) {
        return nullptr;
    }
    PerService & psd = iter->second;
    if (psd.srv.get() != rpcsrv) {
        return nullptr;
    }
    return &psd;
}

ServiceMapHistory & LocalRpcMonitorMap::history() {
    return _history;
}

void LocalRpcMonitorMap::addLocal(const ServiceMapping &mapping,
                                  std::unique_ptr<ScriptCommand> inflight)
{
    LOG(debug, "try local add: mapping %s->%s",
        mapping.name.c_str(), mapping.spec.c_str());
    auto old = _map.find(mapping.name);
    if (old != _map.end()) {
        const PerService & exists = old->second;
        if (exists.spec() == mapping.spec) {
            LOG(debug, "added mapping %s->%s was already present",
                mapping.name.c_str(), mapping.spec.c_str());
            inflight->doneHandler(OkState(0, "already registered"));
            return;
        }
        LOG(warning, "tried addLocal for mapping %s->%s, but already had conflicting mapping %s->%s",
            mapping.name.c_str(), mapping.spec.c_str(),
            exists.name().c_str(), exists.spec().c_str());
        inflight->doneHandler(OkState(FRTE_RPC_METHOD_FAILED, "conflict"));
        return;
    }
    auto [ iter, was_inserted ] =
        _map.try_emplace(mapping.name, localService(mapping, std::move(inflight)));
    LOG_ASSERT(was_inserted);
}

void LocalRpcMonitorMap::add(const ServiceMapping &mapping) {
    _delayedTasks.handleLater(Event::add(mapping));
}

void LocalRpcMonitorMap::remove(const ServiceMapping &mapping) {
    _delayedTasks.handleLater(Event::remove(mapping));
}

void LocalRpcMonitorMap::doAdd(const ServiceMapping &mapping) {
    LOG(debug, "try add: mapping %s->%s",
        mapping.name.c_str(), mapping.spec.c_str());
    auto old = _map.find(mapping.name);
    if (old != _map.end()) {
        PerService & exists = old->second;
        if (exists.spec() == mapping.spec) {
            LOG(debug, "added mapping %s->%s was already present",
                mapping.name.c_str(), mapping.spec.c_str());
            exists.localOnly = false;
            return;
        }
        PerService removed = std::move(exists);
        _map.erase(old);
        LOG(warning, "added mapping %s->%s, but already had conflicting mapping %s->%s",
            mapping.name.c_str(), mapping.spec.c_str(),
            removed.name().c_str(), removed.spec().c_str());
        if (removed.inflight) {
            auto target = std::move(removed.inflight);
            target->doneHandler(OkState(13, "conflict during initialization"));
        }
        if (removed.up) {
            _dispatcher.remove(removed.mapping());
        }
        _delayedTasks.deleteLater(std::move(removed.srv));
    }
    auto [ iter, was_inserted ] =
        _map.try_emplace(mapping.name, globalService(mapping));
    LOG_ASSERT(was_inserted);
}

void LocalRpcMonitorMap::doRemove(const ServiceMapping &mapping) {
    auto iter = _map.find(mapping.name);
    if (iter != _map.end()) {
        PerService removed = std::move(iter->second);
        _map.erase(iter);
        LOG(debug, "remove: mapping %s->%s", mapping.name.c_str(), mapping.spec.c_str());
        if (mapping.spec != removed.spec()) {
            LOG(warning, "inconsistent specs for name '%s': had '%s', but was asked to remove '%s'",
                mapping.name.c_str(),
                removed.spec().c_str(),
                mapping.spec.c_str());
        }
        if (removed.inflight) {
            auto target = std::move(removed.inflight);
            target->doneHandler(OkState(13, "removed during initialization"));
        }
        if (removed.up) {
            _dispatcher.remove(removed.mapping());
        }
        _delayedTasks.deleteLater(std::move(removed.srv));
    } else {
        LOG(debug, "tried to remove non-existing mapping %s->%s",
            mapping.name.c_str(), mapping.spec.c_str());
    }
}

void LocalRpcMonitorMap::notifyFailedRpcSrv(ManagedRpcServer *rpcsrv, std::string) {
    if (auto *psd = lookup(rpcsrv)) {
        LOG(debug, "failed: %s->%s", psd->name().c_str(), psd->spec().c_str());
        if (psd->inflight) {
            auto target = std::move(psd->inflight);
            target->doneHandler(OkState(13, "failed check using listNames callback"));
        }
        if (psd->localOnly) {
            PerService removed = std::move(*psd);
            auto iter = _map.find(removed.name());
            _map.erase(iter);
            if (removed.up) {
                _dispatcher.remove(removed.mapping());
            }
            _delayedTasks.deleteLater(std::move(removed.srv));
        } else if (psd->up) {
            psd->up = false;
            _dispatcher.remove(psd->mapping());
        }
    }
}

void LocalRpcMonitorMap::notifyOkRpcSrv(ManagedRpcServer *rpcsrv) {
    if (auto *psd = lookup(rpcsrv)) {
        LOG(debug, "ok: %s->%s", psd->name().c_str(), psd->spec().c_str());
        if (psd->inflight) {
            auto target = std::move(psd->inflight);
            target->doneHandler(OkState());
        }
        if (! psd->up) {
            psd->up = true;
            _dispatcher.add(psd->mapping());
        }
    }
}

FRT_Supervisor * LocalRpcMonitorMap::getSupervisor() {
    return &_supervisor;
}

} // namespace slobrok
<commit_msg>remove extra abort<commit_after>// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "local_rpc_monitor_map.h"
#include "sbenv.h"
#include <vespa/fnet/frt/supervisor.h>
#include <vespa/log/log.h>
LOG_SETUP(".slobrok.server.local_rpc_monitor_map");

namespace slobrok {

#pragma GCC diagnostic ignored "-Winline"

void LocalRpcMonitorMap::DelayedTasks::PerformTask() {
    {
        std::vector<MUP> deleteAfterSwap;
        std::swap(deleteAfterSwap, _deleteList);
    }
    std::vector<Event> todo;
    std::swap(todo, _queue);
    for (const auto & entry : todo) {
        switch (entry.type) {
        case EventType::ADD:
            _target.doAdd(entry.mapping);
            break;
        case EventType::REMOVE:
            _target.doRemove(entry.mapping);
            break;
        }
    }
}

LocalRpcMonitorMap::LocalRpcMonitorMap(FRT_Supervisor &supervisor)
  : _delayedTasks(supervisor.GetScheduler(), *this),
    _map(),
    _dispatcher(),
    _history(),
    _supervisor(supervisor),
    _subscription(MapSubscription::subscribe(_dispatcher, _history))
{
}

LocalRpcMonitorMap::~LocalRpcMonitorMap() = default;

LocalRpcMonitorMap::PerService *
LocalRpcMonitorMap::lookup(ManagedRpcServer *rpcsrv) {
    auto iter = _map.find(rpcsrv->getName());
    if (iter == _map.end()) {
        return nullptr;
    }
    PerService & psd = iter->second;
    if (psd.srv.get() != rpcsrv) {
        return nullptr;
    }
    return &psd;
}

ServiceMapHistory & LocalRpcMonitorMap::history() {
    return _history;
}

void LocalRpcMonitorMap::addLocal(const ServiceMapping &mapping,
                                  std::unique_ptr<ScriptCommand> inflight)
{
    LOG(debug, "try local add: mapping %s->%s",
        mapping.name.c_str(), mapping.spec.c_str());
    auto old = _map.find(mapping.name);
    if (old != _map.end()) {
        const PerService & exists = old->second;
        if (exists.spec() == mapping.spec) {
            LOG(debug, "added mapping %s->%s was already present",
                mapping.name.c_str(), mapping.spec.c_str());
            inflight->doneHandler(OkState(0, "already registered"));
            return;
        }
        LOG(warning, "tried addLocal for mapping %s->%s, but already had conflicting mapping %s->%s",
            mapping.name.c_str(), mapping.spec.c_str(),
            exists.name().c_str(), exists.spec().c_str());
        inflight->doneHandler(OkState(FRTE_RPC_METHOD_FAILED, "conflict"));
        return;
    }
    auto [ iter, was_inserted ] =
        _map.try_emplace(mapping.name, localService(mapping, std::move(inflight)));
    LOG_ASSERT(was_inserted);
}

void LocalRpcMonitorMap::add(const ServiceMapping &mapping) {
    _delayedTasks.handleLater(Event::add(mapping));
}

void LocalRpcMonitorMap::remove(const ServiceMapping &mapping) {
    _delayedTasks.handleLater(Event::remove(mapping));
}

void LocalRpcMonitorMap::doAdd(const ServiceMapping &mapping) {
    LOG(debug, "try add: mapping %s->%s",
        mapping.name.c_str(), mapping.spec.c_str());
    auto old = _map.find(mapping.name);
    if (old != _map.end()) {
        PerService & exists = old->second;
        if (exists.spec() == mapping.spec) {
            LOG(debug, "added mapping %s->%s was already present",
                mapping.name.c_str(), mapping.spec.c_str());
            exists.localOnly = false;
            return;
        }
        PerService removed = std::move(exists);
        _map.erase(old);
        LOG(warning, "added mapping %s->%s, but already had conflicting mapping %s->%s",
            mapping.name.c_str(), mapping.spec.c_str(),
            removed.name().c_str(), removed.spec().c_str());
        if (removed.inflight) {
            auto target = std::move(removed.inflight);
            target->doneHandler(OkState(13, "conflict during initialization"));
        }
        if (removed.up) {
            _dispatcher.remove(removed.mapping());
        }
        _delayedTasks.deleteLater(std::move(removed.srv));
    }
    auto [ iter, was_inserted ] =
        _map.try_emplace(mapping.name, globalService(mapping));
    LOG_ASSERT(was_inserted);
}

void LocalRpcMonitorMap::doRemove(const ServiceMapping &mapping) {
    auto iter = _map.find(mapping.name);
    if (iter != _map.end()) {
        PerService removed = std::move(iter->second);
        _map.erase(iter);
        LOG(debug, "remove: mapping %s->%s", mapping.name.c_str(), mapping.spec.c_str());
        if (mapping.spec != removed.spec()) {
            LOG(warning, "inconsistent specs for name '%s': had '%s', but was asked to remove '%s'",
                mapping.name.c_str(),
                removed.spec().c_str(),
                mapping.spec.c_str());
        }
        if (removed.inflight) {
            auto target = std::move(removed.inflight);
            target->doneHandler(OkState(13, "removed during initialization"));
        }
        if (removed.up) {
            _dispatcher.remove(removed.mapping());
        }
        _delayedTasks.deleteLater(std::move(removed.srv));
    } else {
        LOG(debug, "tried to remove non-existing mapping %s->%s",
            mapping.name.c_str(), mapping.spec.c_str());
    }
}

void LocalRpcMonitorMap::notifyFailedRpcSrv(ManagedRpcServer *rpcsrv, std::string) {
    if (auto *psd = lookup(rpcsrv)) {
        LOG(debug, "failed: %s->%s", psd->name().c_str(), psd->spec().c_str());
        if (psd->inflight) {
            auto target = std::move(psd->inflight);
            target->doneHandler(OkState(13, "failed check using listNames callback"));
        }
        if (psd->localOnly) {
            PerService removed = std::move(*psd);
            auto iter = _map.find(removed.name());
            _map.erase(iter);
            if (removed.up) {
                _dispatcher.remove(removed.mapping());
            }
            _delayedTasks.deleteLater(std::move(removed.srv));
        } else if (psd->up) {
            psd->up = false;
            _dispatcher.remove(psd->mapping());
        }
    }
}

void LocalRpcMonitorMap::notifyOkRpcSrv(ManagedRpcServer *rpcsrv) {
    if (auto *psd = lookup(rpcsrv)) {
        LOG(debug, "ok: %s->%s", psd->name().c_str(), psd->spec().c_str());
        if (psd->inflight) {
            auto target = std::move(psd->inflight);
            target->doneHandler(OkState());
        }
        if (! psd->up) {
            psd->up = true;
            _dispatcher.add(psd->mapping());
        }
    }
}

FRT_Supervisor * LocalRpcMonitorMap::getSupervisor() {
    return &_supervisor;
}

} // namespace slobrok
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: impframe.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: rt $ $Date: 2006-05-02 17:03:17 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _SFX_IMPFRAME_HXX
#define _SFX_IMPFRAME_HXX

#ifndef _SFXCANCEL_HXX //autogen
#include <svtools/cancel.hxx>
#endif

#pragma hdrstop

#include "frame.hxx"
#include "viewfrm.hxx"                  // SvBorder

class SfxViewFrame;
class SfxObjectShell;

#ifndef _COM_SUN_STAR_FRAME_XCONTROLLER_HPP_
#include <com/sun/star/frame/XController.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XTOPWINDOW_HPP_
#include <com/sun/star/awt/XTopWindow.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XWINDOW_HPP_
#include <com/sun/star/awt/XWindow.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_POSSIZE_HPP_
#include <com/sun/star/awt/PosSize.hpp>
#endif
#ifndef _CPPUHELPER_WEAK_HXX_
#include <cppuhelper/weak.hxx>
#endif

#include <viewsh.hxx>
#include <sfxuno.hxx>

#ifndef FRAME_SEARCH_PARENT
#define FRAME_SEARCH_PARENT     0x00000001
#define FRAME_SEARCH_SELF       0x00000002
#define FRAME_SEARCH_CHILDREN   0x00000004
#define FRAME_SEARCH_CREATE     0x00000008
#endif

class SfxFrame_Impl : public SfxBroadcaster, public SvCompatWeakBase, public SfxListener
{
friend class SfxFrame;

    ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >                     xFrame;
    String                  aFrameIdName;
    sal_uInt32              nType;
    sal_uInt32              nHistoryPos;
    SfxViewFrame*           pCurrentViewFrame;
    SfxObjectShell*         pCurrentObjectShell;
    SfxFrameDescriptor*     pDescr;
    sal_uInt16              nFrameId;
    sal_uInt16              nLocks;
    sal_Bool                bCloseOnUnlock : 1;
    sal_Bool                bClosing : 1;
    sal_Bool                bPrepClosing : 1;
    sal_Bool                bInCancelTransfers : 1;
    sal_Bool                bOwnsBindings : 1;
    sal_Bool                bReleasingComponent : 1;
    sal_Bool                bFocusLocked : 1;
    sal_Bool                bInPlace : 1;
    SfxCancelManager*       pCancelMgr;
    SfxCancellable*         pLoadCancellable;
    SfxFrame*               pFrame;
    const SfxItemSet*       pSet;
    SfxWorkWindow*          pWorkWin;
    SvBorder                aBorder;

                            SfxFrame_Impl( SfxFrame* pAntiImplP ) :
                                SvCompatWeakBase( pAntiImplP ),
                                pFrame( pAntiImplP ),
                                bClosing(sal_False),
                                bPrepClosing(sal_False),
                                nType( 0L ),
                                nHistoryPos( 0 ),
                                nFrameId( 0 ),
                                pCurrentObjectShell( NULL ),
                                pCurrentViewFrame( NULL ),
                                bInCancelTransfers( sal_False ),
                                bCloseOnUnlock( sal_False ),
                                bOwnsBindings( sal_False ),
                                bReleasingComponent( sal_False ),
                                bFocusLocked( sal_False ),
                                bInPlace( sal_False ),
                                nLocks( 0 ),
                                pDescr( NULL ),
                                pCancelMgr( 0 ),
                                pLoadCancellable( 0 ),
                                pSet( 0 ),
                                pWorkWin( 0 )
                            {}

                            ~SfxFrame_Impl() { delete pCancelMgr;
                                               delete pLoadCancellable; }
    virtual void            Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
};

#endif

<commit_msg>INTEGRATION: CWS warnings01 (1.6.66); FILE MERGED 2006/05/23 22:32:52 sb 1.6.66.2: RESYNC: (1.6-1.7); FILE MERGED 2005/11/09 12:03:57 cd 1.6.66.1: #i55991# Make code warning free for gcc<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: impframe.hxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 22:37:55 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _SFX_IMPFRAME_HXX
#define _SFX_IMPFRAME_HXX

#ifndef _SFXCANCEL_HXX //autogen
#include <svtools/cancel.hxx>
#endif

#include "frame.hxx"
#include "viewfrm.hxx"                  // SvBorder

class SfxViewFrame;
class SfxObjectShell;

#ifndef _COM_SUN_STAR_FRAME_XCONTROLLER_HPP_
#include <com/sun/star/frame/XController.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XTOPWINDOW_HPP_
#include <com/sun/star/awt/XTopWindow.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XWINDOW_HPP_
#include <com/sun/star/awt/XWindow.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_POSSIZE_HPP_
#include <com/sun/star/awt/PosSize.hpp>
#endif
#ifndef _CPPUHELPER_WEAK_HXX_
#include <cppuhelper/weak.hxx>
#endif

#include <viewsh.hxx>
#include <sfxuno.hxx>

#ifndef FRAME_SEARCH_PARENT
#define FRAME_SEARCH_PARENT     0x00000001
#define FRAME_SEARCH_SELF       0x00000002
#define FRAME_SEARCH_CHILDREN   0x00000004
#define FRAME_SEARCH_CREATE     0x00000008
#endif

class SfxFrame_Impl : public SfxBroadcaster, public SvCompatWeakBase, public SfxListener
{
friend class SfxFrame;

    ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > xFrame;
    String                    aFrameIdName;
    sal_uInt32                nType;
    sal_uInt32                nHistoryPos;
    SfxViewFrame*             pCurrentViewFrame;
    SfxObjectShell*           pCurrentObjectShell;
    SfxFrameDescriptor*       pDescr;
    sal_uInt16                nFrameId;
    sal_uInt16                nLocks;
    sal_Bool                  bCloseOnUnlock : 1;
    sal_Bool                  bClosing : 1;
    sal_Bool                  bPrepClosing : 1;
    sal_Bool                  bInCancelTransfers : 1;
    sal_Bool                  bOwnsBindings : 1;
    sal_Bool                  bReleasingComponent : 1;
    sal_Bool                  bFocusLocked : 1;
    sal_Bool                  bInPlace : 1;
    SfxCancelManager*         pCancelMgr;
    SfxCancellable*           pLoadCancellable;
    SfxFrame*                 pFrame;
    const SfxItemSet*         pSet;
    SfxWorkWindow*            pWorkWin;
    SvBorder                  aBorder;

    SfxFrame_Impl( SfxFrame* pAntiImplP ) :
                              SvCompatWeakBase( pAntiImplP ),
                              nType( 0L ),
                              nHistoryPos( 0 ),
                              pCurrentViewFrame( NULL ),
                              pCurrentObjectShell( NULL ),
                              pDescr( NULL ),
                              nFrameId( 0 ),
                              nLocks( 0 ),
                              bCloseOnUnlock( sal_False ),
                              bClosing(sal_False),
                              bPrepClosing(sal_False),
                              bInCancelTransfers( sal_False ),
                              bOwnsBindings( sal_False ),
                              bReleasingComponent( sal_False ),
                              bFocusLocked( sal_False ),
                              bInPlace( sal_False ),
                              pCancelMgr( 0 ),
                              pLoadCancellable( 0 ),
                              pFrame( pAntiImplP ),
                              pSet( 0 ),
                              pWorkWin( 0 )
                              {}

    virtual ~SfxFrame_Impl() { delete pCancelMgr; delete pLoadCancellable; }
    virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
};

#endif

<|endoftext|>