Browse Source

Minor cleanup of process class and functions.

merge-requests/365/head
eidheim 10 years ago
parent
commit
c38e3dc7af
  1. 8
      src/CMakeLists.txt
  2. 4
      src/cmake.cc
  3. 2
      src/juci.cc
  4. 7
      src/process.cpp
  5. 7
      src/process.hpp
  6. 19
      src/process_unix.cpp
  7. 23
      src/process_win.cpp
  8. 4
      src/source_clang.cc
  9. 11
      src/terminal.cc
  10. 4
      src/terminal.h
  11. 14
      src/window.cc

8
src/CMakeLists.txt

@ -74,8 +74,8 @@ set(source_files juci.h
cmake.h cmake.h
cmake.cc cmake.cc
dialogs.cc dialogs.cc
process.h process.hpp
process.cc process.cpp
../libclangmm/src/CodeCompleteResults.cc ../libclangmm/src/CodeCompleteResults.cc
../libclangmm/src/CompilationDatabase.cc ../libclangmm/src/CompilationDatabase.cc
@ -93,10 +93,10 @@ set(source_files juci.h
../libclangmm/src/Utility.cc) ../libclangmm/src/Utility.cc)
if(MSYS) if(MSYS)
list(APPEND source_files process_win.cc) list(APPEND source_files process_win.cpp)
list(APPEND source_files dialogs_unix.cc) #dialogs_win.cc does not work any more because of missing SHCreateItemFromParsingName list(APPEND source_files dialogs_unix.cc) #dialogs_win.cc does not work any more because of missing SHCreateItemFromParsingName
else() else()
list(APPEND source_files process_unix.cc) list(APPEND source_files process_unix.cpp)
list(APPEND source_files dialogs_unix.cc) list(APPEND source_files dialogs_unix.cc)
endif() endif()

4
src/cmake.cc

@ -47,9 +47,9 @@ CMake::CMake(const boost::filesystem::path &path) {
bool CMake::create_compile_commands(const boost::filesystem::path &path) { bool CMake::create_compile_commands(const boost::filesystem::path &path) {
Dialog::Message message("Creating "+path.string()+"/compile_commands.json"); Dialog::Message message("Creating "+path.string()+"/compile_commands.json");
auto exit_code=Singleton::terminal->process(Singleton::config->terminal.cmake_command+" . -DCMAKE_EXPORT_COMPILE_COMMANDS=ON", path); auto exit_status=Singleton::terminal->process(Singleton::config->terminal.cmake_command+" . -DCMAKE_EXPORT_COMPILE_COMMANDS=ON", path);
message.hide(); message.hide();
if(exit_code==EXIT_SUCCESS) { if(exit_status==EXIT_SUCCESS) {
#ifdef _WIN32 //Temporary fix to MSYS2's libclang #ifdef _WIN32 //Temporary fix to MSYS2's libclang
auto compile_commands_path=path; auto compile_commands_path=path;
compile_commands_path+="/compile_commands.json"; compile_commands_path+="/compile_commands.json";

2
src/juci.cc

@ -67,7 +67,7 @@ void Application::on_activate() {
it++; it++;
} }
std::thread another_juci_app([this, directory, files_in_directory](){ std::thread another_juci_app([this, directory, files_in_directory](){
Singleton::terminal->async_print("Executing: juci "+directory.string()+files_in_directory); Singleton::terminal->async_print("Executing: juci "+directory.string()+files_in_directory+"\n");
Singleton::terminal->process("juci "+directory.string()+files_in_directory, "", false); Singleton::terminal->process("juci "+directory.string()+files_in_directory, "", false);
}); });
another_juci_app.detach(); another_juci_app.detach();

7
src/process.cc → src/process.cpp

@ -1,4 +1,4 @@
#include "process.h" #include "process.hpp"
#include <iostream> //TODO: remove #include <iostream> //TODO: remove
using namespace std; //TODO: remove using namespace std; //TODO: remove
@ -14,10 +14,7 @@ Process::Process(const std::string &command, const std::string &path,
} }
Process::~Process() { Process::~Process() {
if(stdout_thread.joinable()) close_all();
stdout_thread.join();
if(stderr_thread.joinable())
stderr_thread.join();
} }
bool Process::write(const std::string &data) { bool Process::write(const std::string &data) {

7
src/process.h → src/process.hpp

@ -14,7 +14,7 @@
///Create a new process given command and run path. ///Create a new process given command and run path.
///Note: on Windows it seems impossible to specify which pipes to use. ///Note: on Windows it seems impossible to specify which pipes to use.
///Thus, if read_stdout=nullptr, read_stderr=nullptr and open_stdin=false, ///Thus, if read_stdout==nullptr, read_stderr==nullptr and open_stdin==false,
///the stdout, stderr and stdin are sent to the parent process instead. ///the stdout, stderr and stdin are sent to the parent process instead.
///Compile with -DMSYS_PROCESS_USE_SH to run command using "sh -c [command]" on Windows as well. ///Compile with -DMSYS_PROCESS_USE_SH to run command using "sh -c [command]" on Windows as well.
class Process { class Process {
@ -35,8 +35,8 @@ public:
///Get the process id of the started process. ///Get the process id of the started process.
id_type get_id() {return id;} id_type get_id() {return id;}
///Wait until process is finished, and return exit_code. ///Wait until process is finished, and return exit status.
int get_exit_code(); int get_exit_status();
///Write to stdin. ///Write to stdin.
bool write(const char *bytes, size_t n); bool write(const char *bytes, size_t n);
///Write to stdin. Convenience function using write(const char *, size_t). ///Write to stdin. Convenience function using write(const char *, size_t).
@ -60,6 +60,7 @@ private:
id_type open(const std::string &command, const std::string &path); id_type open(const std::string &command, const std::string &path);
id_type id; id_type id;
void async_read(); void async_read();
void close_all();
}; };
#endif // JUCI_PROCESS_H_ #endif // JUCI_PROCESS_H_

19
src/process_unix.cc → src/process_unix.cpp

@ -1,4 +1,4 @@
#include "process.h" #include "process.hpp"
#include <cstdlib> #include <cstdlib>
#include <unistd.h> #include <unistd.h>
#include <signal.h> #include <signal.h>
@ -100,18 +100,25 @@ void Process::async_read() {
} }
} }
int Process::get_exit_code() { int Process::get_exit_status() {
if(id<=0) if(id<=0)
return -1; return -1;
int exit_code; int exit_status;
waitpid(id, &exit_code, 0); waitpid(id, &exit_status, 0);
close_all();
return exit_status;
}
void Process::close_all() {
if(stdout_thread.joinable()) if(stdout_thread.joinable())
stdout_thread.join(); stdout_thread.join();
if(stderr_thread.joinable()) if(stderr_thread.joinable())
stderr_thread.join(); stderr_thread.join();
close_stdin(); if(stdin_fd)
close_stdin();
if(stdout_fd) { if(stdout_fd) {
close(*stdout_fd); close(*stdout_fd);
stdout_fd.reset(); stdout_fd.reset();
@ -120,8 +127,6 @@ int Process::get_exit_code() {
close(*stderr_fd); close(*stderr_fd);
stderr_fd.reset(); stderr_fd.reset();
} }
return exit_code;
} }
bool Process::write(const char *bytes, size_t n) { bool Process::write(const char *bytes, size_t n) {

23
src/process_win.cc → src/process_win.cpp

@ -1,4 +1,4 @@
#include "process.h" #include "process.hpp"
#include <cstring> #include <cstring>
#include "TlHelp32.h" #include "TlHelp32.h"
@ -7,7 +7,7 @@ using namespace std; //TODO: remove
//Based on the example at https://msdn.microsoft.com/en-us/library/windows/desktop/ms682499(v=vs.85).aspx. //Based on the example at https://msdn.microsoft.com/en-us/library/windows/desktop/ms682499(v=vs.85).aspx.
//Note: on Windows it seems impossible to specify which pipes to use. //Note: on Windows it seems impossible to specify which pipes to use.
//Thus, if read_stdout=nullptr, read_stderr=nullptr and open_stdin=false, the stdout, stderr and stdin are sent to the parent process instead. //Thus, if read_stdout==nullptr, read_stderr==nullptr and open_stdin==false, the stdout, stderr and stdin are sent to the parent process instead.
Process::id_type Process::open(const std::string &command, const std::string &path) { Process::id_type Process::open(const std::string &command, const std::string &path) {
if(open_stdin) if(open_stdin)
stdin_fd=std::unique_ptr<fd_type>(new fd_type); stdin_fd=std::unique_ptr<fd_type>(new fd_type);
@ -164,25 +164,32 @@ void Process::async_read() {
} }
} }
int Process::get_exit_code() { int Process::get_exit_status() {
if(id==0) if(id==0)
return -1; return -1;
DWORD exit_code; DWORD exit_status;
HANDLE process_handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, id); HANDLE process_handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, id);
if(process_handle) { if(process_handle) {
WaitForSingleObject(process_handle, INFINITE); WaitForSingleObject(process_handle, INFINITE);
GetExitCodeProcess(process_handle, &exit_code); GetExitCodeProcess(process_handle, &exit_status);
CloseHandle(process_handle); CloseHandle(process_handle);
} }
else else
exit_code=-1; exit_status=-1;
close_all();
return static_cast<int>(exit_status);
}
void Process::close_all() {
if(stdout_thread.joinable()) if(stdout_thread.joinable())
stdout_thread.join(); stdout_thread.join();
if(stderr_thread.joinable()) if(stderr_thread.joinable())
stderr_thread.join(); stderr_thread.join();
close_stdin(); if(stdin_fd)
close_stdin();
if(stdout_fd) { if(stdout_fd) {
CloseHandle(*stdout_fd); CloseHandle(*stdout_fd);
stdout_fd.reset(); stdout_fd.reset();
@ -191,8 +198,6 @@ int Process::get_exit_code() {
CloseHandle(*stderr_fd); CloseHandle(*stderr_fd);
stderr_fd.reset(); stderr_fd.reset();
} }
return static_cast<int>(exit_code);
} }
bool Process::write(const char *bytes, size_t n) { bool Process::write(const char *bytes, size_t n) {

4
src/source_clang.cc

@ -988,8 +988,8 @@ Source::ClangViewAutocomplete(file_path, project_path, language) {
std::stringstream stdin_stream(get_buffer()->get_text()), stdout_stream; std::stringstream stdin_stream(get_buffer()->get_text()), stdout_stream;
auto exit_code=Singleton::terminal->process(stdin_stream, stdout_stream, command); auto exit_status=Singleton::terminal->process(stdin_stream, stdout_stream, command);
if(exit_code==0) { if(exit_status==0) {
get_source_buffer()->begin_user_action(); get_source_buffer()->begin_user_action();
auto iter=get_buffer()->get_insert()->get_iter(); auto iter=get_buffer()->get_insert()->get_iter();
auto cursor_line_nr=iter.get_line(); auto cursor_line_nr=iter.get_line();

11
src/terminal.cc

@ -2,7 +2,6 @@
#include <iostream> #include <iostream>
#include "logging.h" #include "logging.h"
#include "singletons.h" #include "singletons.h"
#include "process.h"
#include <iostream> //TODO: remove #include <iostream> //TODO: remove
using namespace std; //TODO: remove using namespace std; //TODO: remove
@ -87,7 +86,7 @@ int Terminal::process(const std::string &command, const boost::filesystem::path
return -1; return -1;
} }
return process->get_exit_code(); return process->get_exit_status();
} }
int Terminal::process(std::istream &stdin_stream, std::ostream &stdout_stream, const std::string &command, const boost::filesystem::path &path) { int Terminal::process(std::istream &stdin_stream, std::ostream &stdout_stream, const std::string &command, const boost::filesystem::path &path) {
@ -121,10 +120,10 @@ int Terminal::process(std::istream &stdin_stream, std::ostream &stdout_stream, c
} }
process.close_stdin(); process.close_stdin();
return process.get_exit_code(); return process.get_exit_status();
} }
void Terminal::async_process(const std::string &command, const boost::filesystem::path &path, std::function<void(int exit_code)> callback) { void Terminal::async_process(const std::string &command, const boost::filesystem::path &path, std::function<void(int exit_status)> callback) {
std::thread async_execute_thread([this, command, path, callback](){ std::thread async_execute_thread([this, command, path, callback](){
processes_mutex.lock(); processes_mutex.lock();
stdin_buffer.clear(); stdin_buffer.clear();
@ -146,7 +145,7 @@ void Terminal::async_process(const std::string &command, const boost::filesystem
processes_mutex.unlock(); processes_mutex.unlock();
} }
auto exit_code=process->get_exit_code(); auto exit_status=process->get_exit_status();
processes_mutex.lock(); processes_mutex.lock();
for(auto it=processes.begin();it!=processes.end();it++) { for(auto it=processes.begin();it!=processes.end();it++) {
@ -159,7 +158,7 @@ void Terminal::async_process(const std::string &command, const boost::filesystem
processes_mutex.unlock(); processes_mutex.unlock();
if(callback) if(callback)
callback(exit_code); callback(exit_status);
}); });
async_execute_thread.detach(); async_execute_thread.detach();
} }

4
src/terminal.h

@ -8,7 +8,7 @@
#include <thread> #include <thread>
#include <atomic> #include <atomic>
#include <iostream> #include <iostream>
#include "process.h" #include "process.hpp"
class Terminal : public Gtk::TextView { class Terminal : public Gtk::TextView {
public: public:
@ -29,7 +29,7 @@ public:
Terminal(); Terminal();
int process(const std::string &command, const boost::filesystem::path &path="", bool use_pipes=true); int process(const std::string &command, const boost::filesystem::path &path="", bool use_pipes=true);
int process(std::istream &stdin_stream, std::ostream &stdout_stream, const std::string &command, const boost::filesystem::path &path=""); int process(std::istream &stdin_stream, std::ostream &stdout_stream, const std::string &command, const boost::filesystem::path &path="");
void async_process(const std::string &command, const boost::filesystem::path &path="", std::function<void(int exit_code)> callback=nullptr); void async_process(const std::string &command, const boost::filesystem::path &path="", std::function<void(int exit_status)> callback=nullptr);
void kill_last_async_process(bool force=false); void kill_last_async_process(bool force=false);
void kill_async_processes(bool force=false); void kill_async_processes(bool force=false);

14
src/window.cc

@ -527,9 +527,9 @@ void Window::set_menu_actions() {
compiling=true; compiling=true;
Singleton::terminal->print("Compiling and running "+executable_path.string()+"\n"); Singleton::terminal->print("Compiling and running "+executable_path.string()+"\n");
auto project_path=cmake.project_path; auto project_path=cmake.project_path;
Singleton::terminal->async_process(Singleton::config->terminal.make_command, cmake.project_path, [this, executable_path, project_path](int exit_code){ Singleton::terminal->async_process(Singleton::config->terminal.make_command, cmake.project_path, [this, executable_path, project_path](int exit_status){
compiling=false; compiling=false;
if(exit_code==EXIT_SUCCESS) { if(exit_status==EXIT_SUCCESS) {
auto executable_path_spaces_fixed=executable_path.string(); auto executable_path_spaces_fixed=executable_path.string();
char last_char=0; char last_char=0;
for(size_t c=0;c<executable_path_spaces_fixed.size();c++) { for(size_t c=0;c<executable_path_spaces_fixed.size();c++) {
@ -539,8 +539,8 @@ void Window::set_menu_actions() {
} }
last_char=executable_path_spaces_fixed[c]; last_char=executable_path_spaces_fixed[c];
} }
Singleton::terminal->async_process(executable_path_spaces_fixed, project_path, [this, executable_path](int exit_code){ Singleton::terminal->async_process(executable_path_spaces_fixed, project_path, [this, executable_path](int exit_status){
Singleton::terminal->async_print(executable_path.string()+" returned: "+std::to_string(exit_code)+'\n'); Singleton::terminal->async_print(executable_path.string()+" returned: "+std::to_string(exit_status)+'\n');
}); });
} }
}); });
@ -566,7 +566,7 @@ void Window::set_menu_actions() {
if(cmake.project_path!="") { if(cmake.project_path!="") {
compiling=true; compiling=true;
Singleton::terminal->print("Compiling project "+cmake.project_path.string()+"\n"); Singleton::terminal->print("Compiling project "+cmake.project_path.string()+"\n");
Singleton::terminal->async_process(Singleton::config->terminal.make_command, cmake.project_path, [this](int exit_code){ Singleton::terminal->async_process(Singleton::config->terminal.make_command, cmake.project_path, [this](int exit_status){
compiling=false; compiling=false;
}); });
} }
@ -586,8 +586,8 @@ void Window::set_menu_actions() {
auto run_path=notebook.get_current_folder(); auto run_path=notebook.get_current_folder();
Singleton::terminal->async_print("Running: "+content+'\n'); Singleton::terminal->async_print("Running: "+content+'\n');
Singleton::terminal->async_process(content, run_path, [this, content](int exit_code){ Singleton::terminal->async_process(content, run_path, [this, content](int exit_status){
Singleton::terminal->async_print(content+" returned: "+std::to_string(exit_code)+'\n'); Singleton::terminal->async_print(content+" returned: "+std::to_string(exit_status)+'\n');
}); });
} }
entry_box.hide(); entry_box.hide();

Loading…
Cancel
Save