Example #1
0
  /**
   *  Vertex update function - computes the least square step
   */
  void update(graphchi_vertex<VertexDataType, EdgeDataType> &vertex, graphchi_context &gcontext) {

    //compute only for user nodes
    if (vertex.id() >= std::min(M,(uint)end_user) || vertex.id() < (uint)start_user)
      return;

    vertex_data & vdata = latent_factors_inmem[vertex.id()];
    int howmany = (int)(N*knn_sample_percent);
    assert(howmany > 0 );
    if (vertex.num_outedges() == 0){
       mymutex.lock();
       users_without_ratings++;
       mymutex.unlock();
    }

    vec distances = zeros(howmany);
    ivec indices = ivec::Zero(howmany);
    for (int i=0; i< howmany; i++){
      indices[i]= -1;
    }
    std::vector<bool> curratings;
    curratings.resize(N);
    for(int e=0; e < vertex.num_edges(); e++) {
      //no need to calculate this rating since it is given in the training data reference
      assert(vertex.edge(e)->vertex_id() - M >= 0 && vertex.edge(e)->vertex_id() - M < N);
      curratings[vertex.edge(e)->vertex_id() - M] = true;
    }
    if (knn_sample_percent == 1.0){
      for (uint i=M; i< M+N; i++){
        if (curratings[i-M])
          continue;
        vertex_data & other = latent_factors_inmem[i];
        double dist;
        if (algo == SVDPP)
          svdpp_predict(vdata, other, 0, dist); 
        else if (algo == BIASSGD) 
	  biassgd_predict(vdata, other, 0, dist);
        else if (algo == RBM)
          rbm_predict(vdata, other, 0, dist);
        else assert(false);
        indices[i-M] = i-M;
        distances[i-M] = dist + 1e-10;
      }
    }
    else for (int i=0; i<howmany; i++){
      int random_other = ::randi(M, M+N-1);
      vertex_data & other = latent_factors_inmem[random_other];
      double dist;
      if (algo == SVDPP)
        svdpp_predict(vdata, other, 0, dist); 
      else if (algo == BIASSGD)
        biassgd_predict(vdata, other, 0, dist);
      else if (algo == RBM)
        rbm_predict(vdata, other, 0, dist);
      else assert(false);
        
      indices[i] = random_other-M;
      distances[i] = dist;
    }

    vec out_dist(num_ratings);
    ivec indices_sorted = reverse_sort_index2(distances, indices, out_dist, num_ratings);
    assert(indices_sorted.size() <= num_ratings);
    assert(out_dist.size() <= num_ratings);
    vdata.ids = indices_sorted;
    vdata.ratings = out_dist;
    if (debug)
      printf("Closest is: %d with distance %g\n", (int)vdata.ids[0], vdata.ratings[0]);

    if (vertex.id() % 1000 == 0)
      printf("Computing recommendations for user %d at time: %g\n", vertex.id()+1, mytimer.current_time());
  }
Example #2
0
 /**
  * Causes any threads blocking on "wait_until_empty()" to wake
  * up and evaluate the state of the queue. If the queue is not empty,
  * the threads will return back to sleep immediately. If the queue
  * is empty, all threads will return.
 */
 void broadcast_blocking_empty() {
   m_mutex.lock();
   m_empty_conditional.broadcast();
   m_mutex.unlock();
 }    
    /**
     *  Vertex update function.
     */
    void update(graphchi_vertex<VertexDataType, EdgeDataType> &vertex, graphchi_context &gcontext) {
                if (gcontext.iteration == 0) {
            /* On first iteration, initialize vertex (and its edges). This is usually required, because
             on each run, GraphChi will modify the data files. To start from scratch, it is easiest
             do initialize the program in code. Alternatively, you can keep a copy of initial data files. */

            latentvec_t latentfac;
            latentfac.init();
            set_latent_factor(vertex, latentfac);
        } else {
            mat XtX(NLATENT, NLATENT); 
            XtX.setZero();
            vec Xty(NLATENT);
            Xty.setZero();
            
            // Compute XtX and Xty (NOTE: unweighted)
            for(int e=0; e < vertex.num_edges(); e++) {
                float observation = vertex.edge(e)->get_data().weight;                
                latentvec_t nbr_latent = vertex.edge(e)->get_data().factor;
                for(int i=0; i<NLATENT; i++) {
                    Xty(i) += nbr_latent[i] * observation;
                    for(int j=i; j < NLATENT; j++) {
                        XtX(j,i) += nbr_latent[i] * nbr_latent[j];
                    }
                }
            }
            
            // Symmetrize
            for(int i=0; i <NLATENT; i++)
                for(int j=i + 1; j< NLATENT; j++) XtX(i,j) = XtX(j,i);
            
            // Diagonal
            for(int i=0; i < NLATENT; i++) XtX(i,i) += (LAMBDA) * vertex.num_edges();
            
            // Solve the least squares problem with eigen using Cholesky decomposition
            vec veclatent = XtX.ldlt().solve(Xty);
            
            // Convert to plain doubles (this is useful because now the output data by GraphCHI
            // is plain binary double matrix that can be read, for example, by Matlab).
            latentvec_t newlatent;
            for(int i=0; i < NLATENT; i++) newlatent[i] = veclatent[i];
            
            
            double sqerror = 0;
            bool compute_rmse = (gcontext.iteration == gcontext.num_iterations-1 && vertex.num_outedges() == 0);
            if (compute_rmse) { // Compute RMSE only on "right side" of bipartite graph
                for(int e=0; e < vertex.num_edges(); e++) {        
                    // Compute RMSE
                    float observation = vertex.edge(e)->get_data().weight;
                    latentvec_t nbr_latent = vertex.edge(e)->get_data().factor;
                    double prediction = nbr_latent.dot(newlatent);
                    sqerror += (prediction - observation) * (prediction - observation);                
                    
                }
                rmselock.lock();
                rmse += sqerror;
                rmselock.unlock();
                
                if (vertex.id() % 5000 == 1) {
                    logstream(LOG_DEBUG) << "Computed RMSE for : " << vertex.id() << std::endl;
                }
            }
            
            set_latent_factor(vertex, newlatent); 
            
            if (vertex.id() % 100000 == 1) {
                std::cout <<  gcontext.iteration << ": " << vertex.id() << std::endl;
            }
        }
        
        /* Hack: we need to count ourselves the number of vertices on left
           and right side of the bipartite graph.
           TODO: maybe there should be specialized support for bipartite graphs in GraphChi?
        */
        if (vertex.num_outedges() > 0) {
            // Left side on the bipartite graph
            if (vertex.id() > max_left_vertex) {
                lock.lock();
                max_left_vertex = std::max(vertex.id(), max_left_vertex);
                lock.unlock();
            }
        } else {
            if (vertex.id() > max_right_vertex) {
                lock.lock();
                max_right_vertex = std::max(vertex.id(), max_right_vertex);
                lock.unlock();
            }
        }

    }
Example #4
0
 void end_critical_section() {
  m_mutex.unlock();
 }
Example #5
0
 /**
   Resumes operation of the blocking_queue. Future calls to
   dequeue will proceed as normal.
 */
 inline void start_blocking() {
   m_mutex.lock();
   m_alive = true;
   m_mutex.unlock();
 }
void print_number(int number){
    mu.lock();
    cout << number  << "\n";
    mu.unlock();
}
Example #7
0
	void saveTile(int zoom, int x, int y, string *data) {
		int tmsY = pow(2,zoom) - 1 - y;
		m.lock();
		db << "REPLACE INTO tiles (zoom_level, tile_column, tile_row, tile_data) VALUES (?,?,?,?);" << zoom << x << tmsY && *data;
		m.unlock();
	}
Example #8
0
static int _release(const char *path, struct fuse_file_info *fi) {
    INFO("release [%s]\n", path);

    if (fi->fh < 0 || fi->fh >= FILE_DESC_UPPER_LIMIT) {
        DEBUG("release invalid fd %lu, wtf\n", fi->fh);
        return -EINVAL;
    } else {
        // DEBUG("unregister fd %d\n", fi->fh);
    }
    
    _files_lock.lock();
    auto it = _files.find(path);
    file_entry_t fe;
    int mismatch = 1;
    
    if (it != _files.end()) {
        fe = it->second;
        if (fe->fetched > 0 && fe == fd_fe[fi->fh]) {
            mismatch = 0;
        
            _sync_fe_unsafe(path, fe, fi);
        
            -- fe->open_rc;
            INFO("  release: synced %s, open_rc=%d\n", path, fe->open_rc);
            fd_fe[fi->fh] = NULL;
            fd_touch_size[fi->fh] = 0;
            fe_put(fe);
            
            close(fi->fh);
            fi->fh = -1;
        }
    }

    if (mismatch) {
        if (fd_fe[fi->fh]) {
            fe = fd_fe[fi->fh];
            if (fe->open_rc <= 0) {
                DEBUG("release mismatch\n");
                check_fe(fe);
            } else if (fe->deleted) {
                // if it is removed, no more need to sync
                -- fe->open_rc;
                fd_fe[fi->fh] = NULL;
                fd_touch_size[fi->fh] = 0;
                fe_put(fe);

                close(fi->fh);
            } else {
                // moved to other place
                // sync with real path
                string real_path;
                if (get_real_path(fe, real_path) == 0) {
                    _sync_fe_unsafe(real_path.c_str(), fe, fi);
                } else {
                    DEBUG("get_real_path failed in release\n");
                }

                -- fe->open_rc;
                fd_fe[fi->fh] = NULL;
                fd_touch_size[fi->fh] = 0;
                fe_put(fe);
                
                close(fi->fh);
                fi->fh = -1;
            }

        } else {
            if (fcntl(fi->fh, F_GETFD) == -1) {
                DEBUG("release a NULL fe? the fd %lu is invalid\n", fi->fh);
            } else {
                DEBUG("release a NULL fe? the fd %lu is valid\n", fi->fh);
            }
        }
    }
#ifdef FLUSH_CACHE_ON_RELEASE
    cache_add(0);
#endif
    _files_lock.unlock();

    fi->fh = -1;
    return 0;
}
Example #9
0
    // running in a dedicated thread
    void process() {
        int clear_index;
        {
            unique_lock<mutex> auto_lock(cur_lock);
            cond.wait(auto_lock);
            clear_index = (cur_index + 2) % 3;
            int next_index = (cur_index + 1) % 3;
            cur_index = next_index;
            cur_set = &queue[next_index];
        }
        auto back_set = &queue[clear_index];

        auto it = back_set->begin();
        while (it != back_set->end()) {
            file_entry_t fe = *it;
            grandet_sync_task_t sync_task = NULL;
            grandet_remove_task_t remove_task = NULL;
            _files_lock.lock();
            INFO("processing %s\n", fe->link.c_str());
            if (fe->deleted) {
                INFO("processing deleted fe, size=%ld, fetched=%d, open_rc=%d\n", fe->st.st_size, fe->fetched, fe->open_rc);
            }
            if (fe->deleted && fe->open_rc == 0) {
                // when it is out of tree, no one can open it anymore 
                if (fe->deleted == 1) {
                    string data_path;
                    if (fe->fetched)
                        cache_remove(fe->st.st_size);
                    get_data_path(data_path, _data_store_base, fe->link.c_str());
                    grandet_remove_task_start(fe->link.c_str(), data_path.c_str(), &remove_task);
                    grandet_remove_task_wait(remove_task);
                    grandet_remove_task_end(remove_task);
                    
                    fe->deleted = 2; // avoiding repeated deletion
                }
                fe_put(fe);
            } else {
                // Update
                if (fe->content_dirty) {
                    if (!S_ISREG(fe->st.st_mode)) {
                        DEBUG("flush a non-regular file");
                    }
                    
                    string data_path;
                    get_data_path(data_path, _data_store_base, fe->link.c_str());
                    
                    fe->content_dirty = 0;
                    grandet_sync_task_start(fe->link.c_str(), data_path.c_str(), fe->xattr, &sync_task);
                    
                    _files_lock.unlock();
                    grandet_sync_task_wait(sync_task);
                    grandet_sync_task_end(sync_task);
                    _files_lock.lock();

                    // during the unlock and lock, there may be some
                    // thread writing data in and close, causing
                    // content_dirty be 1 again. Or some one can even
                    // delete it.  In those cases, it will appear in
                    // update queue again.
                    if (fe->open_rc == 0 && fe->fetched == 1 &&
                        fe->content_dirty == 0 && fe->deleted == 0) {
                        // DEBUG("add %s to idle list\n", fe->link.c_str());
                        // LRU
                        if (!list_empty(&fe->u_node))
                            list_del_init(&fe->u_node);
                        INFO("add %s to idle_list (dirty)\n", fe->link.c_str());
                        list_add_before(&_idle_list, &fe->u_node);
                    }
                } else if (fe->fetched == 1 && fe->open_rc == 0) {
                    if (!list_empty(&fe->u_node))
                        list_del_init(&fe->u_node);
                    INFO("add %s to idle_list (clean)\n", fe->link.c_str());
                    list_add_before(&_idle_list, &fe->u_node);
                }
                fe_put(fe);
            }
            _files_lock.unlock();
            ++ it;
        }
        back_set->clear();
    }
 /**
  * Waits for all replies to complete. It is up to the 
  * reply implementation to decrement the counter.
  */
 inline void wait() {
   mut.lock();
   while(!valready) cond.wait(mut);
   mut.unlock();
 }
Example #11
0
void connectHandler(int sockfd, sockaddr_in servaddr, string clientInfo){
  //Attempt to connect to the server.
  //servaddr is server address
  if(connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0){
    fprintf(stderr, "connect error: %s\n", strerror(errno));
    exit(4);
  }
  //send sign and then send info:
  writeMsg("sign", sockfd); 
  //get sign on ack
  string ack; 
  readMsg(ack, sockfd); 
  if(ack.substr(0, 2) != "OK")
    printf("Could not connect to server\n"); 
  //sign onto the server:
  writeMsg(clientInfo, sockfd); 
  //once signed on begin talking to socket
  while(!SHUTDOWN){
    string message = "";
    string command = "";   
    int n; 
    char recvline[MAXLINE + 1]; 
    printf("Enter a command: ");
    std::getline(cin, command);
    if(command.substr(0, 6) == "status"){
      status(); 
    }
    else if(command.substr(0, 8) == "shutdown"){
      message = "gbye"; //server non-interactive command to shut down
      writeMsg(message, sockfd); 
      //talk to the server. (Application-level protocol)
      string cmp; 
      readMsg(cmp, sockfd); 
      if(cmp.substr(0, 4) == "shut"){
	if((close(sockfd)) < 0){
	  printf("error closing socket\n"); 
	}
	SHUTDOWN = true; 
	break;
      }
      else printf("Something went wrong with shutdown, please try again.\n"); 
    }
    else if(command.substr(0, 3) == "ls "){
      handleLsDirectory(command); 
      message = command; 
    }
    else if(command.substr(0, 2) == "ls"){
      handleLs(); //call the ls function to print directory contents
    }
    else if(command.substr(0, 4) == "list"){
      message = "list"; 
      int x;
      writeMsg(message, sockfd); 
      string clients;
      readMsg(clients, sockfd); 
      //display list to user
      displayList(clients); 
    }
    else if(command.substr(0, 5) == "share"){
      //the user wishes to share a file
      vector<string> splitString = split(command, ' '); 
      vector<string> splitFname = split(splitString.at(splitString.size() - 1), '/'); 
      string filename = splitFname.at(splitFname.size() - 1); 
      sharedFiles.lock(); 
      shareable.push_back(filename); 
      sharedFiles.unlock(); 
    }
    else if(command.substr(0, 8) == "download"){
      //split on spaces, store file name and path 
      vector<string> downloadCmd = split(command, ' ');
      if(downloadCmd.size() < 3) 
	printf("Incorrect download syntax. Like this: download <FILENAME> <FILEPATH>\n");
      else{
	string fileName = downloadCmd.at(1); //get the filename 
	string filePath = downloadCmd.at(2); //get the path of the file
	//search to see if file to download has been made available by 
	//one of our clients
	
	int found = searchFiles(fileName);
	if(found == -1){
	  printf("file not available for download\n"); 
	}
	else {
	  //begin download process:
	  //connect to the client that owns the file and ask to download it
	  //that client server then spawns a thread to do the ftp servers job
	  //and the client that wishes to download creates a thread to do the ftp client job
	  string downIp = connectedClients.at(found).ipAddr; 
	  int port = connectedClients.at(found).portNum; 
	  //now that we have this info we can make a connection and start the file transfer process.
	  int newsockfd, n;
	  struct sockaddr_in servaddr;
	  if((newsockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
	    fprintf(stderr, "Socket error.  %s\n", strerror(errno));
	    exit(2);
	  }
	  //build a profile for the client to whom we are going to
	  //communicate.
	  bzero(&servaddr, sizeof(servaddr));
	  servaddr.sin_family = AF_INET;
	  servaddr.sin_port = htons(port);
	   if(inet_pton(AF_INET, downIp.c_str(), &servaddr.sin_addr) <= 0){
	     //changes the ip into binary format for the client address
	     fprintf(stderr, "inet_pton error for %s\n", downIp);
	     exit(3);
	   }
	   //connect to and begin talking to the client
	   if(connect(newsockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0){
	   fprintf(stderr, "connect error: %s\n", strerror(errno));
	   exit(4);
	   }
	   
	   /****
		We are now connected to the file that shares the file our user would like to 
		download. Download protocol begin below.
	   ****/
	   
	   string send = "file";
	   writeMsg(send, newsockfd); //tell the client who shares the file that we want to download
	   string ack = ""; 
	   readMsg(ack, newsockfd); //so our writes don't get read in on one line? 
	   string fname = "download.txt"; 
	   writeMsg(fname, newsockfd); //tell the client the name of the file we want to download
	   recftp(newsockfd, filePath.c_str()); //call recftp and begin to download file
	}
      }
    }
    else {
      printf("the command you entered was not a valid command, please try again.\n"); 
    }
  }
  return; 
}
Example #12
0
static void
downloadTopicPicsAndSeed ( const string& topic_url,
                           const string& proxy_addr,
                           const string& path,
                           unsigned timeout_download_pic,
                           bool b_show_info )
{
    AichengTopicWebpage aicheng_topics_webpage(topic_url, proxy_addr);

    // ready for the basename of pictures and seed.
    // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    string base_name; // from topic title

    // 0) delete the web logo info;
    // 1) clear the "/" in topictitle string, if the "/" present in filename,
    // linux will treat it as directory, again, clear the "\" for windows;
    static const vector<string> keyword_logos_list = { " 亚洲无码区 bt下载 - powered by phpwind.net",
                                                       " 亚洲有码区 bt下载 - powered by phpwind.net",
                                                       " 欧美区 bt下载 - powered by phpwind.net",
                                                       " 动漫区 bt下载 - powered by phpwind.net",
                                                       "|亚洲无码区 - bt下载 爱城 bt下载 ",
                                                       "亚洲无码区 - bt下载 爱城 bt下载 ",
                                                       "|亚洲有码区 - bt下载 爱城 bt下载 ",
                                                       "亚洲有码区 - bt下载 爱城 bt下载 ",
                                                       "|动漫区 - bt下载 爱城 bt下载 ",
                                                       "动漫区 - bt下载 爱城 bt下载 ",
                                                       "|欧美区 - bt下载 爱城 bt下载 ",
                                                       "欧美区 - bt下载 爱城 bt下载 " };
    const string& topic_webpage_title = aicheng_topics_webpage.getTitle();
    auto keyword_logo_pos = string::npos;
    for (const auto& f : keyword_logos_list) {
        keyword_logo_pos = topic_webpage_title.find(f);
        if (string::npos != keyword_logo_pos) {
            break;
        }
    }
    remove_copy_if( topic_webpage_title.cbegin(),
                    (string::npos == keyword_logo_pos) ? topic_webpage_title.cend() : topic_webpage_title.cbegin() + (int)keyword_logo_pos,
                    back_inserter(base_name),
                    [] (char ch) {return( '|' == ch || // invalid chars in windows-style filename
                                          '/' == ch ||
                                          '<' == ch ||
                                          '>' == ch ||
                                          '?' == ch ||
                                          '*' == ch ||
                                          ':' == ch ||
                                          '\\' == ch );} );

    // 2) the path + filename max length must less than pathconf(, _PC_NAME_MAX)
    const unsigned filename_max_length_without_postfix = (unsigned)pathconf(path.c_str(), _PC_NAME_MAX)
                                                         - string("99").size() // picture number
                                                         - string(".torrent").size();
    if (base_name.size() >= filename_max_length_without_postfix) {
        // the filename too long to create file. the way as following doesn't work, case filename encoding error: 
        // base_name.resize(filename_max_length_without_postfix - 1), because this is string on char not wstring on wchar.
        // there is another stupid way, random name from 'a' to 'z'
        base_name.resize(16);
        generate( base_name.begin(), base_name.end(), 
                  [] () {return('a' + rand() % ('z' - 'a'));} );
        base_name = "(rename)" + base_name;
    }
    // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
 
    // download all pictures
    vector<string> fail_download_pics_urls_list;
    bool b_download_pics_success = aicheng_topics_webpage.downloadAllPictures( path,
                                                                               base_name,
                                                                               timeout_download_pic,
                                                                               fail_download_pics_urls_list,
                                                                               32 );

    // download seed
    bool b_downloaded_seed_success = false;
    if (!aicheng_topics_webpage.getSeedUrl().empty()) {
        JandownSeedWebpage jan_seed_webpage(aicheng_topics_webpage.getSeedUrl(), proxy_addr);
        b_downloaded_seed_success = jan_seed_webpage.downloadSeed(path, base_name);
    }

    // show result info
    if (!b_show_info) {
        return;
    }
    static const string success_info("success");
    static const string fail_info = RichTxt::foreground_red + "failure" + RichTxt::reset_all;
    g_mtx.lock();
    cout << "  \"" << base_name << "\" - ";
    if (b_download_pics_success && b_downloaded_seed_success) {
        cout << success_info; 
    } else {
        cout << fail_info << " (download error from " << topic_url << ". ";
        if (!b_download_pics_success) {
            cout << "pictures error: ";
            copy(fail_download_pics_urls_list.cbegin(), fail_download_pics_urls_list.cend(), ostream_iterator<const string&>(cout, ", "));
            cout << "\b\b";
        }
        if (!b_downloaded_seed_success) {
            if (!b_download_pics_success) {
                cout << "; ";
            }
            cout << "seed error: " << aicheng_topics_webpage.getSeedUrl();
        }
        cout << ")";
    }
    cout << endl;
    g_mtx.unlock();
}
Example #13
0
int main(int argc, char** argv)
{
    ros::init(argc, argv, "pathplanner");

    ros::NodeHandle nh;

    ros::Subscriber map_sub = nh.subscribe("/map", 1, map_callback);

    ros::Subscriber pose_sub = nh.subscribe("/odom_combined", 1, position_callback);

    ros::Subscriber waypoint_sub = nh.subscribe("/waypoint", 1, waypoint_callback);

    disp_path_pub = nh.advertise<nav_msgs::Path>("/path_display", 1);

    act_path_pub = nh.advertise<igvc_msgs::action_path>("/path", 1);

    expanded_pub = nh.advertise<pcl::PointCloud<pcl::PointXYZ> >("/expanded", 1);

    double baseline = 0.93;

    search_problem.Map = pcl::PointCloud<pcl::PointXYZ>().makeShared();
    search_problem.GoalThreshold = 1.0;
    search_problem.Threshold = 0.5;
    search_problem.Speed = 1.0;
    search_problem.Baseline = baseline;
    search_problem.DeltaT = [](double distToStart)->double {
        return 0.66*(log2(distToStart + 1) + 0.1);
    };
    search_problem.MinimumOmega = -0.6;
    search_problem.MaximumOmega = 0.61;
    search_problem.DeltaOmega = 0.5;
    search_problem.PointTurnsEnabled = false;
    search_problem.ReverseEnabled = false;
	search_problem.maxODeltaT = 0.1;

    ros::Rate rate(3);
    while(ros::ok())
    {
        ros::spinOnce();

        /* Do not attempt to plan a path if the path length would be greater than 100ft (~30m).
         * This should only happen when we have received either a waypoint or position estimate, but not both.
         * Long paths take forever to compute, and will freeze up this node.
         */
        auto distance_to_goal = search_problem.Start.distTo(search_problem.Goal);
        if(!received_waypoint || distance_to_goal == 0 || distance_to_goal > 60)
            continue;

        planning_mutex.lock();
        // TODO only replan if needed.
        auto path = GraphSearch::AStar(search_problem, expanded_callback);
        if(disp_path_pub.getNumSubscribers() > 0)
        {
            nav_msgs::Path disp_path_msg;
            disp_path_msg.header.stamp = ros::Time::now();
            disp_path_msg.header.frame_id = "map";
            if(path.getStates()->empty())
                path.getStates()->push_back(search_problem.Start);
            for(auto loc : *(path.getStates()))
            {
                geometry_msgs::PoseStamped pose;
                pose.header.stamp = disp_path_msg.header.stamp;
                pose.header.frame_id = disp_path_msg.header.frame_id;
                pose.pose.position.x = loc.x;
                pose.pose.position.y = loc.y;
                disp_path_msg.poses.push_back(pose);
            }
            disp_path_pub.publish(disp_path_msg);

            igvc_msgs::action_path act_path_msg;
            act_path_msg.header.stamp = ros::Time::now();
            act_path_msg.header.frame_id = "map";
            for(auto action : *(path.getActions()))
            {
                igvc_msgs::velocity_pair vels;
                vels.header.stamp = act_path_msg.header.stamp;
                vels.header.frame_id = act_path_msg.header.frame_id;
                double radius = action.V / action.W;
                vels.right_velocity = (radius - baseline/2.) * action.W;
                vels.left_velocity = (radius + baseline/2.) * action.W;
                vels.duration = action.DeltaT;
                act_path_msg.actions.push_back(vels);
            }
            act_path_pub.publish(act_path_msg);
        }

        planning_mutex.unlock();

        rate.sleep();
    }

    return 0;
}
Example #14
0
void VideoTextureCache::addPicData(VideoPic *pVideoPic)
{
    mtx.lock();
    s_pAsyncVideoPicQueue->push(pVideoPic);
    mtx.unlock();
}
Example #15
0
void mainChat(){
	string str,temp;
	int status;
	status=1; //0 if logout

	header2();
	while(status==1){
		cout << endl;
		kunci.lock();
		messageNotifier();
		cout << username << "> ";
		getline(cin >> ws,str);
		kunci.unlock();
		//logout
		if(str.compare("logout")==0){
			status=0;
			logout();
		}
		//message
		else if(str.substr(0,8).compare("message ")==0){
			temp = str.substr(8);
			sendMessage(temp);
		}
		//create group
		else if(str.substr(0,7).compare("create ")==0){
			temp = str.substr(7);
			groupCreate(temp);
		}
		//join group
		else if(str.substr(0,5).compare("join ")==0){
			temp = str.substr(5);
			groupJoin(temp);
		}
		//leave group
		else if(str.substr(0,6).compare("leave ")==0){
			temp = str.substr(6);
			groupLeave(temp);
		}
		//show chat history
		else if(str.substr(0,5).compare("show ")==0){
			temp = str.substr(5);
			readChat2(temp);
			deleteNotifSender(temp);
			//moveToBottom(..pathnya dimana..);
		}
		else if(str.compare("help")==0){
			header2();
		}
		//exit
		else if(str.compare("exit")==0){
			status=0;
			active = false;
			closeConnection();
			exit(0);
		}
		//empty input
		else if(str.compare("")==0){
			//do nothing
		}
		//wrong input
		else{
			cout <<"Unknown input, please type \'help\' for help." <<endl;
		}
	}
}
Example #16
0
// open file with lock held
int _open_unsafe(const char *path, struct fuse_file_info *fi) {
    int ret = 0;
    file_entry_t fe;
    auto it = _files.find(path);
    if (it == _files.end()) {
        ret = -ENOENT;
    } else {
        // XXX PERM CHECK?
        fe = it->second;

        if (!S_ISREG(fe->st.st_mode)) {
            DEBUG("open a non-regular file [%s]\n", path);
            return -EINVAL;
        }

        // from now on we dont care about path
        
        string data_path;
        get_data_path(data_path, _data_store_base, fe->link.c_str());
        
      again:
        if (fe->fetched == 0) {
            grandet_fetch_task_t task = fe->fetch_task;
            int r = 0;
            if (task == NULL) {
                INFO("open start grandet_fetch_task link = [%s] size = %ld\n",
                     fe->link.c_str(), fe->st.st_size);
                cache_add(fe->st.st_size);
                r = grandet_fetch_task_start(path, fe->link.c_str(), data_path.c_str(), fe->st.st_size, &task);
                fe->fetch_task = task;
            } else
                grandet_fetch_task_get(task);

            fe_get(fe);
            
            if (r == 0) {                
                _files_lock.unlock();
                INFO("wait grandet_fetch_task {{\n");
                grandet_fetch_task_wait(task);
                INFO("wait grandet_fetch_task }}\n");
                _files_lock.lock();
            }

            grandet_fetch_task_put(task);
            
            // during the lock and unlock, the file entry may be
            // deleted, moved, or evicted. But it must be accessible
            // since we added a reference

            if (fe->deleted) {
                fe_put(fe);
                return -ENOENT;
            }

            // here fe is still in tree, so put the reference safely
            fe_put(fe);

            if (fe->fetch_task != task) {
                // do those check again to open the data link
                goto again;
            } else {
                // only the first one who put will get here, where a existing node
                // is just fetched from grandet
                fe->fetch_task = NULL;
                if (access(data_path.c_str(), F_OK) == 0) {
                    // test whether we failed
                    fe->fetched = 1;
                } else {
                    DEBUG("fetch failed, restore cache fetched = %d\n", fe->fetched);
                    ret = -ENOENT;
                    cache_remove(fe->st.st_size);
                }
            }
        }

        // when we reach here, the file entry may be just created,
        // fetched, moved (but not evicted), but at least it is a
        // existing regular file, and we know its data link.

        if (ret == 0) {
            int h = open(data_path.c_str(), fi->flags);
            if (h == -1) {
                ret = -errno;
            } else if (h >= FILE_DESC_UPPER_LIMIT) {
                DEBUG("open get a fd that exceeds upper limit\n");
                close(h);
                ret = -ENOMEM;
                h = -1;
            } else {
                struct stat st;
                fstat(h, &st);
                INFO("open get fd %d, len = %ld fe_len = %ld\n", h, st.st_size, fe->st.st_size);
                fi->fh = h;
                
                fd_fe[h] = fe;
                fd_touch_size[h] = 0;
                
                fe_get(fe);
                ++ fe->open_rc;
                if (fe->open_rc == 1) {
                    if (!list_empty(&fe->u_node)) {
                        INFO("remove %s from idle_list\n", fe->link.c_str());
                        list_del_init(&fe->u_node);
                    }
                }
            }
        }    
    }

    return ret;
}
Example #17
0
/* For sanitys sake I'm going to comment this one, since it's a
   doozy. The other two lookup functions are basically the same thing,
   so I'm only going to comment this one, and those comments also
   apply to the others.*/
lockptr<User> acquireUser(const long userID){
  userCacheManager.lock();
  // First thing, we check if we already have this user object cached.
  auto cacheIt = userCache.find(userID);
  // If we do, we can just lock the cached version, return it, and
  // we're done.
  if (cacheIt != userCache.end()){
    auto entry = cacheIt->second;
    userCacheManager.unlock();
    return lockptr<User>(entry->item, &(entry->m));
  }

  // If not, we want to first make room in the cache for a new object,
  // by kicking out the oldest one.
  for(auto it = userCache.begin(); it != userCache.end(); ++it){
    // Each cache entry has a ttl, which is initialized at the size of
    // the cache, and decremented every time we want to add something
    // new to the cache, so that if always we kick out objects with
    // non-positive TTL, we restrict our cache to the proper
    // size. Unfortunately, we might need to keep things in our cache
    // even if they have run out of life, because another thread might
    // still be holding on to them. This means that our cache might
    // grow above cachesize, but will never grow above
    // cachesize+number_of_threads.
    auto entry = it->second;
    if(--entry->ttl < 1 && entry->m.try_lock()){
      long entryID = it->first;
      // Now that we've decided to kick out this element, we need to
      // figure out if we still have a file mapping for it.  If not,
      // that means that that object was deleted already, so there's
      // no need to try to save it's state to a file.
      auto mapIt = userFileMap.find(entryID);
      if (mapIt != userFileMap.end())
	// If we do have a file mapping, we want to write out it's
	// current state, since any actions taken on it since it was
	// last pulled are in memory, but not in the file.
	entry->item->writeToFile(mapIt->second);
      // Since we, the cache, own the pointers to these objects, we
      // now need to clean it up, and finally remove the item from the
      // cache.
      delete entry->item;
      entry->m.unlock();
      delete entry;
      userCache.erase(it);
    }
  }
  // Next, we need to try to find the mapping for the file of the new
  // object we want to pull in. This might not succeed, since the
  // client could have an old ID for a user that has since been
  // deleted, so wee need to check for that, and return nullptr if so.
  auto mapIt = userFileMap.find(userID);
  if (mapIt == userFileMap.end()){
    userCacheManager.unlock();
    return lockptr<User>(nullptr, nullptr);
  }
  // Here, we finally load in the new User, taking ownership of the
  // pointer to it. Then, we update the cache with this new object,
  // and return the new object. We're done!
  User* loadedUser = User::readFromFile(mapIt->second);
  cacheRecord<User>* newEntry = new cacheRecord<User>();
  newEntry->item = loadedUser;
  newEntry->ttl = USER_CACHESIZE;
  userCache[userID] = newEntry;
  userCacheManager.unlock();
  return lockptr<User>(loadedUser, &(newEntry->m));
}
Example #18
0
int
_create(const char *path, mode_t mode, struct fuse_file_info *fi) {
    fi->flags &= O_TRUNC | O_CREAT | 0x3;
    fi->fh = -1;
    INFO("create [%s], mode = %04o, flags = %x\n", path, mode, fi->flags);

    int ret = 0;
    string t_p, t_b;
    split_path(path, t_p, t_b);

    _files_lock.lock();
    map<string, file_entry_t>::iterator p_it, t_it;
    if ((p_it = _files.find(t_p)) == _files.end()) {
        ret = -ENOENT;
    } else if ((t_it = _files.find(path)) != _files.end()) {
        if (fi->flags & O_EXCL) {
            ret = -EEXIST;
        } else {
            ret = _open_unsafe(path, fi);
        }
    } else {
        // path is ready and target file does not exists
        file_entry_t p = p_it->second;

        boost::uuids::uuid key_uuid = boost::uuids::random_generator()();
        string data_key = boost::lexical_cast<string>(key_uuid);

        string data_path;
        get_data_path(data_path, _data_store_base, data_key.c_str());

        int h = open(data_path.c_str(), fi->flags, mode);
        if (h == -1) {
            ret = -errno;
        } else {
            if (ftruncate(h, 0)) {
                DEBUG("FAIL to ftruncate, err=%d\n", errno);
            }
            
            file_entry_t fe = new_fe();
        
            fe->name = t_b;
            fe->st.st_mode = S_IFREG | (mode & 0777);
            fe->st.st_size = 0;

            fe->parent = p;
            list_add(&p->c_list, &fe->c_node);
            _files[path] = fe;

            fe->link = data_key;
            INFO("create assign key [%s] to [%s]\n", fe->link.c_str(), path);
            
            if (h >= FILE_DESC_UPPER_LIMIT) {
                DEBUG("create exceed the max number of fd\n");
                close(h);
                h = -1;
                ret = -ENOMEM;
            } else {
                fi->fh = h;
                
                fd_fe[h] = fe;
                fd_touch_size[h] = 0;
                
                fe_get(fe);
            
                fe->fetched = 1;
                fe->content_dirty = 1;
                fe->open_rc = 1;

                _update_queue.add(fe);
            }

            redis_sync(path, fe);
        }
    }
    _files_lock.unlock();

    if (ret < 0) {
        DEBUG("create [%s] error %d\n", path, ret);
    } else {
        // DEBUG("register fd %d [%s] %x\n", fi->fh, path, fi->flags);
    }

    return ret;
}
Example #19
0
	void writeMetadata(string key, string value) {
		m.lock();
		db << "REPLACE INTO metadata (name,value) VALUES (?,?);" << key << value;
		m.unlock();
	}
Example #20
0
 void lock(error_code& ec = throws)
 {
     return lock("mutex::lock", ec);
 }
int main(int argc, char* argv[])
{

    long thread_id;

    // ATOI Casts a string as an int.
    thread_count = atoi(argv[4]); //total number of threads - from command line

    // Refer to prog2.pdf for meaning of variables
    N = atoi(argv[3]);

    M = atoi(argv[2]);

    L = atoi(argv[1]);

    // Resizing the matrices

    /* Dynamic array allocation from stack overflow ,gsamaras
    int** ary = new int*[rowCount];
    for(int i = 0; i < rowCount; ++i)
        ary[i] = new int[colCount];
    */
    // Creates dynamic Array
    MatrixA = new long *[L];
    for(int i = 0; i < L; i++)
        MatrixA[i] = new long [M];

    //initializes values for Said array
    for(int i = 0; i < L; i++)
        for(int j = 0; j < M; j++)
            MatrixA[i][j] = i + j;

    // Creates dynamic Array
    MatrixB = new long *[M];
    for(int i = 0; i < M; i++)
        MatrixB[i] = new long [N];

    //initializes values for Said array
    for(int i = 0; i < M; i++)
        for(int j = 0; j < N; j++)
            MatrixB[i][j] = i + j + 1;

    //creates output matrix
    MatrixC = new long *[L];
    for(int i = 0; i < L; i++)
        MatrixC[i] = new long [N];



    // Defines the number of threads.
    pthread_t myThreads[thread_count]; //define threads

    // Locking
    mutualExclusion.lock();
    cout<<"L ="<<L<<", m="<<M<<", n="<<N<<endl;
    mutualExclusion.unlock();
    //Unlocking

    //Start time
    double start,stop;
    GET_TIME(start);


    //creates a certain number of threads
    for(thread_id = 0; thread_id < thread_count; thread_id++){

        pthread_create(&myThreads[thread_id], NULL, matrixMultiply, (void*)thread_id);
    }

    //wait until all threads finis
    for(thread_id = 0; thread_id < thread_count; thread_id++)
        pthread_join(myThreads[thread_id], NULL);

    //stop time
    GET_TIME(stop);


    //printing the results
    cout<<"-----------------------First 20x10-------------------"<<endl;
    printMatrixFirst();
    cout << "\n\n";

    cout<<"-----------------------Last  20x10-------------------"<<endl;
    printMatrixLast();

    double total = stop - start;
    cout << "Total Time: " << total << " seconds."<<endl;


    return 0;
}//main
Example #22
0
 bool try_lock(error_code& ec = throws)
 {
     return try_lock("mutex::try_lock", ec);
 }
Example #23
0
 //! Returns true if the queue is empty
 inline bool empty() { 
   m_mutex.lock();
   bool res = m_queue.empty();
   m_mutex.unlock();
   return res;
 }
Example #24
0
int main(int argc, char** argv){

     if (argc != 7) {
    cerr << "Wrong call\n";
    return 1;
  }
  
  // [Dirtracker][PortTracker][NodoActualDir][NodoActualPort][DirFiles][Delay]
  // ./Client localhost 5555 localhost 6666 Temp 5
  string TrackerDir=argv[1];
  string TrackerPort=argv[2];
  string NodeDir=argv[3];
  string NodePort=argv[4];

  string TrackerConnect="tcp://"+TrackerDir+":"+TrackerPort; 
  string NodeListenerConnect="tcp://*:"+NodePort;
  string NodeDirSite="tcp://"+NodeDir+":"+NodePort; 

  Tpath= argv[5];
  cout<<"Path: "<<Tpath<<endl;
  int Time = atoi(argv[6]);

  zctx_t* context = zctx_new();

  void* Tracker = zsocket_new(context, ZMQ_DEALER);
  int a = zsocket_connect(Tracker, TrackerConnect.c_str());
  cout << "connecting to Tracker: "<<TrackerConnect << (a == 0 ? " OK" : "ERROR") << endl;
  cout << "Listening! Tracker" << endl;

  void* NodeListener = zsocket_new(context, ZMQ_ROUTER);
  int b = zsocket_bind(NodeListener,NodeListenerConnect.c_str());
  cout << "Listening! Nodes at : "<<NodeListenerConnect << (b == 0 ? " OK" : "ERROR") << endl; 
  

  zmq_pollitem_t items[] = {{Tracker, 0, ZMQ_POLLIN, 0},
                            {NodeListener, 0, ZMQ_POLLIN, 0}};

  DirFiles(Tpath);                          
  SplitFiles(Tpath);
  DirFiles(Tpath);                           
  RegPeer(Tracker,NodeDirSite);

  thread Poll(PollItems,Tracker,NodeListener,items,context,NodeDirSite);
  Poll.detach();
  
  for(int i=0;i<FileList.size();i++){
      cout<<"Item ["<<i<<"]: "<<FileList[i]<<endl;
     }
  int op=0;   
  while(op!=7){   
  cout<<"LL      iii lll  '     TTTTTTT                                     tt"<<endl;    
  cout<<"LL          lll '''      TTT    oooo  rr rr  rr rr    eee  nn nnn  tt"<<endl;    
  cout<<"LL      iii lll ''       TTT   oo  oo rrr  r rrr  r ee   e nnn  nn tttt"<<endl;  
  cout<<"LL      iii lll          TTT   oo  oo rr     rr     eeeee  nn   nn tt"<<endl;    
  cout<<"LLLLLLL iii lll          TTT    oooo  rr     rr      eeeee nn   nn  tttt"<<endl; 
  cout<<"::::::::::::::::::::::::::::::"<<endl;
  cout<<"::::::::     MENU    :::::::::"<<endl;
  cout<<"::::::::::::::::::::::::::::::"<<endl;
  cout<<":: 1-> Search :::"<<endl;
  cout<<":: 2-> Download :::"<<endl;
  cout<<":: 3-> Play Song (sin extensión) :::"<<endl;
  cout<<":: 4-> Pause :::"<<endl;
  cout<<":: 5-> Stop :::"<<endl;
  cout<<":: 6-> Play in memory :::"<<endl;
  cout<<":: 7-> Exit :::"<<endl;  
  
  cin>>op;

  
  switch (op){
    case 1 :
    QuerySearch(Tracker);
    break;
    
    case 2 :
    QueryListFile(Tracker);
    break;

    case 3 :
    Save.lock();
    if(Cont1!=Cont2){
      cout<<"No se puede reproducir, canción incompleta , \n ¡espera hasta que se termine de descargar!"<<endl;
      }else{
        string Song;
        cin>>Song;
        string sentence= "7z x Temp/"+Song+".7z.001";
        system(sentence.c_str());
        if(music.openFromFile("Temp/"+Song+".ogg")){
          music.stop();
          music.play();
        }
      }
    Save.unlock();
    break;
    
    case 4 :
    music.pause();
    break;
    
    case 5 :
    music.stop();
    break;


    case 6 :
    music.play();
    break;
         
  }
  
}
  DirFiles(Tpath);        
  Disconnect(Tracker,NodeDirSite);
  

  Poll.~thread();
 
  zctx_destroy(&context);
  return 0;
 
}
Example #25
0
 /**
  * Causes any threads currently blocking on a dequeue to wake up
  * and evaluate the state of the queue. If the queue is empty,
  * the threads will return back to sleep immediately. If the queue
  * is destroyed through stop_blocking, all threads will return. 
  */
 void broadcast() {
   m_mutex.lock();
   m_conditional.broadcast();
   m_mutex.unlock();
 }
	namespace data_service_EXT{
		using namespace std;
		struct SyncInfo;

		using SyncInfoPtr 		= unique_ptr<SyncInfo>;
		using MsgRcvr___EXT		= tuple<PredWrapper_EXT, CbWrapper_EXT, SyncInfoPtr>;
		using HandlerBuffer 	=	forward_list<MsgRcvr___EXT>;
		HandlerBuffer buffer__;
		mutex buffer__Mutex;
		struct SyncInfo
		{
			mutex m{};
			condition_variable cv{};
			bool sync	{false};
			bool rdy	{false};
			SyncInfo(){}
			void arm()
			{
				sync = true;
				rdy = false;
			}
			bool wait_for(int64_t wait_time_us)
			{
				if (!sync)
					return false;
				unique_lock<mutex> lk{m};
				return cv.wait_for(lk, chrono::microseconds(wait_time_us), [this]{return rdy;});
			}
			void disarm()
			{
				if (!sync)
					return;
				sync 	= false;
				rdy 	= true;
				unique_lock<mutex> lk{m};
				cv.notify_one();
			}
		};

		struct TxHandle::Data
		{
			HandlerBuffer::iterator it_;
		};

		TxHandle::TxHandle(PredWrapper_EXT&& pred, CbWrapper_EXT&& cb):data{new Data{}}
		{
			buffer__Mutex.lock();
			data->it_ = buffer__.emplace_after(buffer__.before_begin(), move(pred),move(cb), SyncInfoPtr(new SyncInfo{}));
			buffer__Mutex.unlock();
		}
		TxHandle::~TxHandle()
		{
			delete data;
		}
		void TxHandle::arm()
		{
			get<2>(*data->it_)->arm();
		}
		bool TxHandle::wait_for(int64_t micro_sec)
		{
			return get<2>(*data->it_)->wait_for(micro_sec);
		}
		void TxHandle::remove()
		{
			buffer__Mutex.lock();
			swap(*(data->it_), buffer__.front());
			buffer__.pop_front();
			buffer__Mutex.unlock();
		}

		TxHandle registerHandlers(PredWrapper_EXT&& pred, CbWrapper_EXT&& cb)
		{
			return TxHandle{move(pred), move(cb)};
		}

		void	removeHandler(TxHandle& h)
		{
			h.remove();
		}

		void request(const AFMessage_EXT& msg)
		{
			sendAPSMessageStruct(const_cast<AFMessage_EXT*>(&msg));
		}

		void request(AFMessage_EXT& msg, PredWrapper_EXT&& pred, CbWrapper_EXT&& cb, int64_t wait_time_us)
		{
			//using namespace std::chrono;
			auto h = registerHandlers(move(pred),move(cb));
			h.arm();
			sendAPSMessageStruct(&msg);

			//auto t0 = steady_clock::now();
			if (h.wait_for(wait_time_us)){
				//LOG_MESSAGE("got it");
			}
//			else
//			{
//				LOG_MESSAGE("did not get it");
//			}
//			auto t1 = steady_clock::now();
//			LOG_MESSAGE("duration = %d ms", duration_cast<milliseconds>(t1 - t0).count());
			removeHandler(h);
		}

		bool indicate(AFMessage_EXT& msg)
		{
			bool served = false;
			buffer__Mutex.lock();
			for (auto& y : buffer__)
			{
				if (get<0>(y)(msg))
				{
					get<1>(y)(msg);
					get<2>(y)->disarm();
					served = true;
					break;
				}
			}
			buffer__Mutex.unlock();
			return served;
		}

		int apsMessageIndicate(AFMessage_EXT* message)
		{
			if (indicate(*message)) {	return 0; }

			if (Endpoint* x = selfptr()->endpointPtr(message->dstEndpoint()))
			{
				//if (x->messageHandler != NULL)
					//x->messageHandler(message);
				//else
				//{
					//x->handleAPSMessage(*message);
					//aps::data_service::indicate(*message);
				//}
			}

			return 0;
		}
		void init()
		{
			kapi::mtaf::register_AFMessage_EXT_cb(apsMessageIndicate);
			//mtaf::regi(apsMessageIndicate);
		}
	} //data_service
Example #27
0
 void begin_critical_section() {
   m_mutex.lock();
 }
		TxHandle::TxHandle(PredWrapper_EXT&& pred, CbWrapper_EXT&& cb):data{new Data{}}
		{
			buffer__Mutex.lock();
			data->it_ = buffer__.emplace_after(buffer__.before_begin(), move(pred),move(cb), SyncInfoPtr(new SyncInfo{}));
			buffer__Mutex.unlock();
		}
Example #29
0
static void fftwf_free_thr(void *p) {
	static mutex m;
	m.lock();
	fftwf_free(p);
	m.unlock();
}
Example #30
0
void sendreceive_usfmresources ()
{
  mutex_sendreceive_usfmresources.lock ();
  bool bail_out = sendreceive_usfmresources_running;
  mutex_sendreceive_usfmresources.unlock ();
  if (bail_out) return;
  mutex_sendreceive_usfmresources.lock ();
  sendreceive_usfmresources_running = true;
  mutex_sendreceive_usfmresources.unlock ();
  
  
  Database_UsfmResources database_usfmresources = Database_UsfmResources ();
  Webserver_Request request;
  Sync_Logic sync_logic = Sync_Logic (&request);

  
  Database_Logs::log (sendreceive_usfmresources_sendreceive_text (), Filter_Roles::translator ());
  
 
  string address = Database_Config_General::getServerAddress ();
  int port = Database_Config_General::getServerPort ();
  string url = client_logic_url (address, port, sync_usfmresources_url ());

  
  map <string, string> post;
  string error;
  string response;
  
  
  // Request the checksum of all USFM resources from the server.
  // Compare it with the local checksum.
  // If the two match: Ready.
  post ["a"] = convert_to_string (Sync_Logic::usfmresources_get_total_checksum);
  response = sync_logic.post (post, url, error);
  if (!error.empty ()) {
    Database_Logs::log (sendreceive_usfmresources_text () + "Failure getting total checksum: " + error, Filter_Roles::translator ());
    sendreceive_usfmresources_done ();
    return;
  }
  string checksum = Sync_Logic::usfm_resources_checksum ();
  if (response == checksum) {
    Database_Logs::log (sendreceive_usfmresources_up_to_date_text (), Filter_Roles::translator ());
    sendreceive_usfmresources_done ();
    return;
  }
  
  
  // Request a list of all USFM resources available on the server.
  post ["a"] = convert_to_string (Sync_Logic::usfmresources_get_resources);
  response = sync_logic.post (post, url, error);
  if (!error.empty ()) {
    Database_Logs::log (sendreceive_usfmresources_text () + "Failure getting resources: " + error, Filter_Roles::translator ());
    sendreceive_usfmresources_done ();
    return;
  }
  vector <string> server_resources = filter_string_explode (response, '\n');
  
  
  // Delete any resource on the local client but not on the server.
  vector <string> client_resources = database_usfmresources.getResources ();
  vector <string> resources = filter_string_array_diff (client_resources, server_resources);
  for (auto & resource : resources) {
    database_usfmresources.deleteResource (resource);
  }
  
  
  // Deal with each USFM resource individually.
  for (auto & resource : server_resources) {
    
    
    // Request the checksum of the resources from the server.
    // Compare it with the checksum of the local resource.
    // If they match: Go to the next resource.
    post ["a"] = convert_to_string (Sync_Logic::usfmresources_get_resource_checksum);
    post ["r"] = resource;
    response = sync_logic.post (post, url, error);
    if (!error.empty ()) {
      Database_Logs::log (sendreceive_usfmresources_text () + "Failure getting checksum of resource: " + error, Filter_Roles::translator ());
      sendreceive_usfmresources_done ();
      return;
    }
    checksum = Sync_Logic::usfm_resource_checksum (resource);
    if (response == checksum) {
      continue;
    }
    

    // Request a list of all books in the resource on the server.
    post ["a"] = convert_to_string (Sync_Logic::usfmresources_get_books);
    post ["r"] = resource;
    response = sync_logic.post (post, url, error);
    if (!error.empty ()) {
      Database_Logs::log (sendreceive_usfmresources_text () + "Failure getting books of resource: " + error, Filter_Roles::translator ());
      sendreceive_usfmresources_done ();
      return;
    }
    vector <int> server_books;
    vector <string> sbooks = filter_string_explode (response, '\n');
    for (auto & book : sbooks) server_books.push_back (convert_to_int (book));

    
    // Delete any books from the client that are not on the server.
    vector <int> client_books = database_usfmresources.getBooks (resource);
    vector <int> books = filter_string_array_diff (client_books, server_books);
    for (auto & book : books) {
      database_usfmresources.deleteBook (resource, book);
    }
    
    
    // Deal with each book individually.
    for (auto & book : server_books) {
      
      
      // Request checksum of this book,
      // compare it with the local checksum,
      // and skip the book if the checksums match.
      post ["a"] = convert_to_string (Sync_Logic::usfmresources_get_book_checksum);
      post ["r"] = resource;
      post ["b"] = convert_to_string (book);
      response = sync_logic.post (post, url, error);
      if (!error.empty ()) {
        Database_Logs::log (sendreceive_usfmresources_text () + "Failure getting checksum of resource book: " + error, Filter_Roles::translator ());
        sendreceive_usfmresources_done ();
        return;
      }
      checksum = Sync_Logic::usfm_resource_book_checksum (resource, book);
      if (response == checksum) {
        continue;
      }
      
      
      string bookname = Database_Books::getEnglishFromId (book);
      Database_Logs::log (sendreceive_usfmresources_text () + "Synchronizing " + resource + " " + bookname, Filter_Roles::translator ());
      
      
      // Retrieve a list of chapters in the $book from the server.
      post ["a"] = convert_to_string (Sync_Logic::usfmresources_get_chapters);
      post ["r"] = resource,
      post ["b"] = convert_to_string (book);
      response = sync_logic.post (post, url, error);
      if (!error.empty ()) {
        Database_Logs::log (sendreceive_usfmresources_text () + "Failure getting chapters of resource book: " + error, Filter_Roles::translator ());
        sendreceive_usfmresources_done ();
        return;
      }
      vector <int> server_chapters;
      vector <string> schapters = filter_string_explode (response, '\n');
      for (auto & chapter : schapters) server_chapters.push_back (convert_to_int (chapter));
      
      
      // Delete local chapters not found on the server.
      vector <int> client_chapters = database_usfmresources.getChapters (resource, book);
      vector <int> chapters = filter_string_array_diff (client_chapters, server_chapters);
      for (auto & chapter : chapters) {
        database_usfmresources.deleteChapter (resource, book, chapter);
      }
      
      
      // Go through each chapter individually.
      for (auto & chapter : server_chapters) {

        
        // Get the checksum of the chapter as it is on the server.
        post ["a"] = convert_to_string (Sync_Logic::usfmresources_get_chapter_checksum);
        post ["r"] = resource;
        post ["b"] = convert_to_string (book);
        post ["c"] = convert_to_string (chapter);
        response = sync_logic.post (post, url, error);
        if (!error.empty ()) {
          Database_Logs::log (sendreceive_usfmresources_text () + "Failure getting checksum of resource chapter: " + error, Filter_Roles::translator ());
          sendreceive_usfmresources_done ();
          return;
        }
        checksum = Sync_Logic::usfm_resource_chapter_checksum (resource, book, chapter);
        if (response == checksum) {
          continue;
        }
        
        
        // Download the chapter from the server, and store it locally on the client.
        post ["a"] = convert_to_string (Sync_Logic::usfmresources_get_chapter);
        post ["r"] = resource;
        post ["b"] = convert_to_string (book);
        post ["c"] = convert_to_string (chapter);
        response = sync_logic.post (post, url, error);
        if (!error.empty ()) {
          Database_Logs::log (sendreceive_usfmresources_text () + "Failure downloading resource chapter: " + error, Filter_Roles::translator ());
          sendreceive_usfmresources_done ();
          return;
        }
        database_usfmresources.storeChapter (resource, book, chapter, response);
      }
    }
  }

  
  // Done.
  Database_Logs::log (sendreceive_usfmresources_text () + "Now up to date", Filter_Roles::translator ());
  sendreceive_usfmresources_done ();
}