Changeset f42b4fbef76944dc292983208ef62e144ab7031f
- Timestamp:
- 10/02/11 00:47:50 (20 months ago)
- Children:
- 36ef11202b7e4345f2402d8ea9cf6395ac857081
- Parents:
- 5483a52daf9dca6aa6cbfafc7d6d050456d49dd3
- git-committer:
- Nedko Arnaudov <nedko@arnaudov.name> / 2011-10-02T00:47:50Z+0300
- Files:
-
- 10 modified
-
common/dirhelpers.c (modified) (3 diffs)
-
common/dirhelpers.h (modified) (1 diff)
-
daemon/app_supervisor.c (modified) (21 diffs)
-
daemon/app_supervisor.h (modified) (2 diffs)
-
daemon/loader.c (modified) (4 diffs)
-
daemon/loader.h (modified) (2 diffs)
-
daemon/room_load.c (modified) (2 diffs)
-
gui/dialogs.c (modified) (1 diff)
-
gui/gladish.ui (modified) (1 diff)
-
gui/world_tree.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
common/dirhelpers.c
r0266594 rf42b4fb 26 26 27 27 #include "../common.h" 28 #include "catdup.h" 28 29 29 30 #include <sys/types.h> … … 32 33 #include <errno.h> 33 34 #include <stdarg.h> 35 #include <dirent.h> 34 36 35 37 bool check_dir_exists(const char * dirname) … … 241 243 return ret; 242 244 } 245 246 bool ladish_rmdir_recursive(const char * dirpath) 247 { 248 DIR * dir; 249 struct dirent * dentry_ptr; 250 char * entry_fullpath; 251 struct stat st; 252 bool success; 253 254 success = false; 255 256 dir = opendir(dirpath); 257 if (dir == NULL) 258 { 259 log_error("Cannot open directory '%s': %d (%s)", dirpath, errno, strerror(errno)); 260 goto exit; 261 } 262 263 while ((dentry_ptr = readdir(dir)) != NULL) 264 { 265 if (strcmp(dentry_ptr->d_name, ".") == 0 || 266 strcmp(dentry_ptr->d_name, "..") == 0) 267 { 268 continue; 269 } 270 271 entry_fullpath = catdup3(dirpath, "/", dentry_ptr->d_name); 272 if (entry_fullpath == NULL) 273 { 274 log_error("catdup() failed"); 275 goto close; 276 } 277 278 if (stat(entry_fullpath, &st) != 0) 279 { 280 log_error("failed to stat '%s': %d (%s)", entry_fullpath, errno, strerror(errno)); 281 } 282 else 283 { 284 if (S_ISDIR(st.st_mode)) 285 { 286 if (!ladish_rmdir_recursive(entry_fullpath)) 287 { 288 goto free; 289 } 290 } 291 else 292 { 293 if (unlink(entry_fullpath) < 0) 294 { 295 log_error("unlink('%s') failed. errno = %d (%s)", dirpath, errno, strerror(errno)); 296 goto free; 297 } 298 } 299 } 300 301 free(entry_fullpath); 302 } 303 304 if (rmdir(dirpath) < 0) 305 { 306 log_error("rmdir('%s') failed. errno = %d (%s)", dirpath, errno, strerror(errno)); 307 } 308 else 309 { 310 success = true; 311 } 312 313 goto close; 314 315 free: 316 free(entry_fullpath); 317 close: 318 closedir(dir); 319 exit: 320 return success; 321 } 322 323 bool ladish_rotate(const char * src, const char * dst, unsigned int max_backups) 324 { 325 size_t len = strlen(dst) + 100; 326 char paths[2][len]; 327 struct stat st; 328 char * path; 329 const char * older_path; 330 bool oldest_found; 331 unsigned int backup; 332 333 oldest_found = false; 334 older_path = NULL; 335 backup = max_backups; 336 while (backup > 0) 337 { 338 path = paths[backup % 2]; 339 snprintf(path, len, "%s.%u", dst, backup); 340 341 if (stat(path, &st) != 0) 342 { 343 if (!oldest_found && errno == ENOENT) 344 { 345 log_info("\"%s\" does not exist", path); 346 goto next; 347 } 348 349 log_error("Failed to stat \"%s\": %d (%s)", path, errno, strerror(errno)); 350 return false; 351 } 352 353 if (!S_ISDIR(st.st_mode)) 354 { 355 log_error("\"%s\" exists but is not directory.", path); 356 return false; 357 } 358 359 oldest_found = true; 360 361 if (backup < max_backups) 362 { 363 ASSERT(older_path != NULL); 364 log_info("rename '%s' -> '%s'", path, older_path); 365 if (rename(path, older_path) != 0) 366 { 367 log_error("rename('%s' -> '%s') failed. errno = %d (%s)", path, older_path, errno, strerror(errno)); 368 return false; 369 } 370 } 371 else 372 { 373 /* try to remove dst.max_backups */ 374 log_info("rmdir '%s'", path); 375 if (!ladish_rmdir_recursive(path)) 376 { 377 return false; 378 } 379 } 380 381 next: 382 older_path = path; 383 backup--; 384 } 385 386 log_info("rename '%s' -> '%s'", dst, path); 387 if (rename(dst, path) != 0 && errno != ENOENT) 388 { 389 log_error("rename('%s' -> '%s') failed. errno = %d (%s)", dst, path, errno, strerror(errno)); 390 return false; 391 } 392 393 log_info("rename '%s' -> '%s'", src, dst); 394 if (rename(src, dst) != 0) 395 { 396 log_error("rename('%s' -> '%s') failed. errno = %d (%s)", src, dst, errno, strerror(errno)); 397 return false; 398 } 399 400 return true; 401 } -
common/dirhelpers.h
r0266594 rf42b4fb 31 31 bool ensure_dir_exist(const char * dirname, int mode); 32 32 bool ensure_dir_exist_varg(int mode, ...); 33 bool ladish_rmdir_recursive(const char * dirname); 34 bool ladish_rotate(const char * src, const char * dst, unsigned int max_backups); 33 35 34 36 #endif /* #ifndef DIRHELPERS_H__805193D2_2662_40FA_8814_AF8A4E08F4B0__INCLUDED */ -
daemon/app_supervisor.c
r5483a52 rf42b4fb 41 41 #include "../common/catdup.h" 42 42 #include "../common/dirhelpers.h" 43 #include "jack_session.h" 43 44 44 45 struct ladish_app … … 49 50 char * name; 50 51 char * commandline; 52 char * js_commandline; 51 53 bool terminal; 52 54 char level[MAX_LEVEL_CHARCOUNT]; … … 68 70 char * opath; 69 71 char * dir; 72 73 char * js_dir; 74 char * js_temp_dir; 75 unsigned int pending_js_saves; 76 void * save_callback_context; 77 ladish_save_complete_callback save_callback; 78 70 79 char * project_name; 71 80 uint64_t version; … … 86 95 87 96 if (strcmp(level, LADISH_APP_LEVEL_0) != 0 && 88 strcmp(level, LADISH_APP_LEVEL_1) != 0&& 89 strcmp(level, LADISH_APP_LEVEL_LASH) != 0) 97 strcmp(level, LADISH_APP_LEVEL_1) != 0 && 98 strcmp(level, LADISH_APP_LEVEL_LASH) != 0 && 99 strcmp(level, LADISH_APP_LEVEL_JACKSESSION) != 0) 90 100 { 91 101 return false; … … 155 165 156 166 supervisor_ptr->dir = NULL; 167 168 supervisor_ptr->js_temp_dir = NULL; 169 supervisor_ptr->js_dir = NULL; 170 supervisor_ptr->pending_js_saves = 0; 171 supervisor_ptr->save_callback_context = NULL; 172 supervisor_ptr->save_callback = NULL; 173 157 174 supervisor_ptr->project_name = NULL; 158 175 … … 207 224 free(app_ptr->name); 208 225 free(app_ptr->commandline); 226 free(app_ptr->js_commandline); 209 227 free(app_ptr); 210 228 } … … 251 269 } 252 270 271 static void ladish_js_save_complete(struct ladish_app_supervisor * supervisor_ptr) 272 { 273 struct list_head * node_ptr; 274 struct ladish_app * app_ptr; 275 bool success; 276 277 ASSERT(supervisor_ptr->js_temp_dir != NULL); 278 ASSERT(supervisor_ptr->js_dir != NULL); 279 ASSERT(supervisor_ptr->pending_js_saves == 0); 280 281 /* find whether all strdup() calls for new commandlines succeeded */ 282 list_for_each(node_ptr, &supervisor_ptr->applist) 283 { 284 app_ptr = list_entry(node_ptr, struct ladish_app, siblings); 285 if (app_ptr->state == LADISH_APP_STATE_STARTED && 286 strcmp(app_ptr->level, LADISH_APP_LEVEL_JACKSESSION) == 0 && 287 app_ptr->js_commandline == NULL) 288 { /* a strdup() call has failed, free js commandline buffers allocated by succeeded strdup() calls */ 289 list_for_each(node_ptr, &supervisor_ptr->applist) 290 { 291 app_ptr = list_entry(node_ptr, struct ladish_app, siblings); 292 free(app_ptr->js_commandline); 293 app_ptr->js_commandline = NULL; 294 } 295 goto fail_rm_temp_dir; 296 } 297 } 298 299 /* move js_dir to js_dir.1; move js_temp_dir to js_dir */ 300 success = ladish_rotate(supervisor_ptr->js_temp_dir, supervisor_ptr->js_dir, 10); 301 if (!success) 302 { 303 goto fail_rm_temp_dir; 304 } 305 306 list_for_each(node_ptr, &supervisor_ptr->applist) 307 { 308 app_ptr = list_entry(node_ptr, struct ladish_app, siblings); 309 if (app_ptr->state == LADISH_APP_STATE_STARTED && 310 strcmp(app_ptr->level, LADISH_APP_LEVEL_JACKSESSION) == 0) 311 { 312 ASSERT(app_ptr->commandline != NULL); 313 ASSERT(app_ptr->js_commandline != NULL); 314 free(app_ptr->commandline); 315 app_ptr->commandline = app_ptr->js_commandline; 316 app_ptr->js_commandline = NULL; 317 } 318 } 319 320 goto done; 321 322 fail_rm_temp_dir: 323 if (!ladish_rmdir_recursive(supervisor_ptr->js_temp_dir)) 324 { 325 log_error("Cannot remove JS temp dir '%s'", supervisor_ptr->js_temp_dir); 326 } 327 328 done: 329 free(supervisor_ptr->js_temp_dir); 330 supervisor_ptr->js_temp_dir = NULL; 331 332 supervisor_ptr->save_callback(supervisor_ptr->save_callback_context, success); 333 supervisor_ptr->save_callback = NULL; 334 supervisor_ptr->save_callback_context = NULL; 335 } 336 253 337 #define supervisor_ptr ((struct ladish_app_supervisor *)supervisor_handle) 254 338 … … 334 418 { 335 419 log_error("invalid level '%s'", level); 336 return NULL; 420 goto fail; 421 } 422 423 if (strcmp(level, LADISH_APP_LEVEL_JACKSESSION) == 0 && 424 supervisor_ptr->dir == NULL) 425 { 426 log_error("jack session apps need directory"); 427 goto fail; 337 428 } 338 429 … … 341 432 { 342 433 log_error("malloc of struct ladish_app failed"); 343 return NULL;434 goto fail; 344 435 } 345 436 … … 348 439 { 349 440 log_error("strdup() failed for app name"); 350 free(app_ptr); 351 return NULL; 441 goto free_app; 352 442 } 353 443 … … 356 446 { 357 447 log_error("strdup() failed for app commandline"); 358 free(app_ptr->name);359 free(app_ptr);360 return NULL; 361 }448 goto free_name; 449 } 450 451 app_ptr->js_commandline = NULL; 362 452 363 453 app_ptr->dbus_name = NULL; … … 419 509 420 510 return (ladish_app_handle)app_ptr; 511 512 free_name: 513 free(app_ptr->name); 514 free_app: 515 free(app_ptr); 516 fail: 517 return NULL; 421 518 } 422 519 … … 623 720 } 624 721 722 #define app_ptr ((struct ladish_app *)context) 723 724 static void ladish_js_app_save_complete(void * context, const char * commandline) 725 { 726 log_info("JS app saved, commandline '%s'", commandline); 727 ASSERT(app_ptr->supervisor->js_temp_dir != NULL); 728 729 ASSERT(app_ptr->js_commandline == NULL); 730 app_ptr->js_commandline = strdup(commandline); 731 if (app_ptr->js_commandline == NULL) 732 { 733 log_error("strdup() failed for JS app '%s' commandline '%s'", app_ptr->name, commandline); 734 } 735 736 if (app_ptr->supervisor->pending_js_saves != 1) 737 { 738 ASSERT(app_ptr->supervisor->pending_js_saves > 1); 739 app_ptr->supervisor->pending_js_saves--; 740 log_info("%u more JS apps are still saving", app_ptr->supervisor->pending_js_saves); 741 return; 742 } 743 744 log_info("Last JS app saved"); 745 app_ptr->supervisor->pending_js_saves = 0; 746 747 ladish_js_save_complete(app_ptr->supervisor); 748 } 749 750 #undef app_ptr 751 625 752 static inline void ladish_app_initiate_save(struct ladish_app * app_ptr) 626 753 { … … 629 756 { 630 757 ladish_app_initiate_lash_save(app_ptr, app_ptr->supervisor->dir != NULL ? app_ptr->supervisor->dir : g_base_dir); 758 } 759 else if (strcmp(app_ptr->level, LADISH_APP_LEVEL_JACKSESSION) == 0) 760 { 761 log_info("Initiating JACK session save for '%s'", app_ptr->name); 762 ladish_js_save_app(app_ptr->uuid, app_ptr->supervisor->js_temp_dir, app_ptr, ladish_js_app_save_complete); 631 763 } 632 764 else if (strcmp(app_ptr->level, LADISH_APP_LEVEL_1) == 0) … … 659 791 bool lifeless; 660 792 793 free(supervisor_ptr->js_temp_dir); 794 supervisor_ptr->js_temp_dir = NULL; 795 free(supervisor_ptr->js_dir); 796 supervisor_ptr->js_dir = NULL; 661 797 free(supervisor_ptr->dir); 662 798 supervisor_ptr->dir = NULL; … … 701 837 { 702 838 char * dup; 839 char * js_dir; 840 841 ASSERT(supervisor_ptr->pending_js_saves == 0); 703 842 704 843 dup = strdup(dir); … … 709 848 } 710 849 711 if (supervisor_ptr->dir != NULL) 712 { 713 free(supervisor_ptr->dir); 714 } 715 850 js_dir = catdup(dir, "/js_apps"); 851 if (js_dir == NULL) 852 { 853 log_error("catdup() failed to compose supervisor js dir path"); 854 free(dup); 855 return false; 856 } 857 858 free(supervisor_ptr->dir); 716 859 supervisor_ptr->dir = dup; 860 861 free(supervisor_ptr->js_dir); 862 supervisor_ptr->js_dir = js_dir; 717 863 718 864 return true; … … 812 958 bool ladish_app_supervisor_start_app(ladish_app_supervisor_handle supervisor_handle, ladish_app_handle app_handle) 813 959 { 960 char uuid_str[37]; 961 char * js_dir; 962 bool ret; 963 814 964 app_ptr->zombie = false; 815 965 816 966 ASSERT(app_ptr->pid == 0); 817 967 818 if (!loader_execute( 819 supervisor_ptr->name, 820 supervisor_ptr->project_name, 821 app_ptr->name, 822 supervisor_ptr->dir != NULL ? supervisor_ptr->dir : "/", 823 app_ptr->terminal, 824 app_ptr->commandline, 825 &app_ptr->pid)) 968 if (strcmp(app_ptr->level, LADISH_APP_LEVEL_JACKSESSION) == 0) 969 { 970 uuid_unparse(app_ptr->uuid, uuid_str); 971 js_dir = catdup4(supervisor_ptr->js_dir, "/", uuid_str, "/"); 972 if (js_dir == NULL) 973 { 974 log_error("catdup4() failed to compose app jack session dir"); 975 return false; 976 } 977 } 978 else 979 { 980 js_dir = NULL; 981 } 982 983 ret = loader_execute( 984 supervisor_ptr->name, 985 supervisor_ptr->project_name, 986 app_ptr->name, 987 supervisor_ptr->dir != NULL ? supervisor_ptr->dir : "/", 988 js_dir, 989 app_ptr->terminal, 990 app_ptr->commandline, 991 &app_ptr->pid); 992 993 free(js_dir); 994 995 if (!ret) 826 996 { 827 997 return false; … … 869 1039 ladish_app_send_signal(app_ptr, SIGKILL, false); 870 1040 app_ptr->state = LADISH_APP_STATE_KILL; 871 }872 873 void ladish_app_save(ladish_app_handle app_handle)874 {875 ladish_app_initiate_save(app_ptr);876 1041 } 877 1042 … … 1007 1172 struct list_head * node_ptr; 1008 1173 struct ladish_app * app_ptr; 1174 bool success; 1175 1176 ASSERT(supervisor_ptr->js_temp_dir == NULL); 1177 ASSERT(supervisor_ptr->pending_js_saves == 0); 1178 list_for_each(node_ptr, &supervisor_ptr->applist) 1179 { 1180 app_ptr = list_entry(node_ptr, struct ladish_app, siblings); 1181 if (app_ptr->state == LADISH_APP_STATE_STARTED && 1182 strcmp(app_ptr->level, LADISH_APP_LEVEL_JACKSESSION) == 0) 1183 { 1184 ASSERT(app_ptr->js_commandline == NULL); 1185 supervisor_ptr->pending_js_saves++; 1186 } 1187 } 1188 1189 if (supervisor_ptr->pending_js_saves > 0) 1190 { 1191 ASSERT(supervisor_ptr->dir != NULL); 1192 supervisor_ptr->js_temp_dir = catdup(supervisor_ptr->dir, "/js_apps.tmpXXXXXX"); 1193 if (supervisor_ptr->js_temp_dir == NULL) 1194 { 1195 log_error("catdup() failed to compose supervisor js temp dir path template"); 1196 goto reset_js_pending_saves; 1197 } 1198 1199 if (mkdtemp(supervisor_ptr->js_temp_dir) == NULL) 1200 { 1201 log_error("mkdtemp('%s') failed. errno = %d (%s)", supervisor_ptr->js_temp_dir, errno, strerror(errno)); 1202 goto free_js_temp_dir; 1203 } 1204 1205 log_info("saving %u JACK session apps to '%s'", supervisor_ptr->pending_js_saves, supervisor_ptr->js_temp_dir); 1206 1207 supervisor_ptr->save_callback_context = context; 1208 supervisor_ptr->save_callback = callback; 1209 } 1210 else 1211 { 1212 ASSERT(supervisor_ptr->save_callback_context == NULL); 1213 ASSERT(supervisor_ptr->save_callback == NULL); 1214 } 1009 1215 1010 1216 list_for_each(node_ptr, &supervisor_ptr->applist) … … 1025 1231 } 1026 1232 1027 callback(context, true); 1233 success = true; 1234 goto exit; 1235 1236 free_js_temp_dir: 1237 free(supervisor_ptr->js_temp_dir); 1238 supervisor_ptr->js_temp_dir = NULL; 1239 reset_js_pending_saves: 1240 supervisor_ptr->pending_js_saves = 0; 1241 success = false; 1242 exit: 1243 if (supervisor_ptr->pending_js_saves == 0) 1244 { 1245 ASSERT(supervisor_ptr->save_callback == NULL); 1246 ASSERT(callback != NULL); 1247 callback(context, success); 1248 } 1028 1249 } 1029 1250 -
daemon/app_supervisor.h
r5483a52 rf42b4fb 36 36 #define LADISH_APP_STATE_KILL 3 /**< @brief app is being force killed */ 37 37 38 #define MAX_LEVEL_CHARCOUNT 1 0/* includes terminating nul char */38 #define MAX_LEVEL_CHARCOUNT 12 /* includes terminating nul char */ 39 39 40 40 /** … … 427 427 428 428 /** 429 * Initiate save of app internal state. The app must be in started state.430 *431 * @param[in] app_handle Handle of app432 */433 void ladish_app_save(ladish_app_handle app_handle);434 435 /**436 429 * Initiate restore of app internal state. The app must be in started state. 437 430 * -
daemon/loader.c
r60aaa49 rf42b4fb 264 264 const char * commandline, 265 265 const char * working_dir, 266 const char * session_dir, 266 267 bool run_in_terminal, 267 268 const char * vgraph_name, … … 295 296 { 296 297 setenv("LADISH_PROJECT_NAME", project_name, true); 298 } 299 300 if (session_dir != NULL) 301 { 302 setenv("SESSION_DIR", session_dir, true); 297 303 } 298 304 … … 522 528 const char * app_name, 523 529 const char * working_dir, 530 const char * session_dir, 524 531 bool run_in_terminal, 525 532 const char * commandline, … … 635 642 set_ldpreload(); 636 643 637 loader_exec_program(commandline, working_dir, run_in_terminal, vgraph_name, project_name, app_name);644 loader_exec_program(commandline, working_dir, session_dir, run_in_terminal, vgraph_name, project_name, app_name); 638 645 639 646 return false; /* We should never get here */ -
daemon/loader.h
r99b1ab0 rf42b4fb 3 3 * LADI Session Handler (ladish) 4 4 * 5 * Copyright (C) 2009, 2010 Nedko Arnaudov <nedko@arnaudov.name>5 * Copyright (C) 2009, 2010, 2011 Nedko Arnaudov <nedko@arnaudov.name> 6 6 * 7 7 ************************************************************************** … … 36 36 const char * app_name, 37 37 const char * working_dir, 38 const char * session_dir, 38 39 bool run_in_terminal, 39 40 const char * commandline, -
daemon/room_load.c
r68716ee rf42b4fb 872 872 XML_SetUserData(parser, &parse_context); 873 873 874 ladish_app_supervisor_set_directory(room_ptr->app_supervisor, project_dir); 875 if (!ladish_app_supervisor_set_project_name(room_ptr->app_supervisor, room_ptr->project_name)) 876 { 877 ladish_app_supervisor_set_project_name(room_ptr->app_supervisor, NULL); 878 } 879 874 880 xmls = XML_ParseBuffer(parser, bytes_read, XML_TRUE); 875 881 if (xmls == XML_STATUS_ERROR && !parse_context.error) … … 886 892 ladish_graph_dump(room_ptr->graph); 887 893 ladish_app_supervisor_dump(room_ptr->app_supervisor); 888 889 ladish_app_supervisor_set_directory(room_ptr->app_supervisor, project_dir);890 if (!ladish_app_supervisor_set_project_name(room_ptr->app_supervisor, room_ptr->project_name))891 {892 ladish_app_supervisor_set_project_name(room_ptr->app_supervisor, NULL);893 }894 894 895 895 ladish_graph_trick_dicts(room_ptr->graph); -
gui/dialogs.c
r4f7a90a rf42b4fb 56 56 gtk_widget_set_sensitive(GTK_WIDGET(level1_button), TRUE); 57 57 gtk_widget_set_sensitive(GTK_WIDGET(level2lash_button), TRUE); 58 gtk_widget_set_sensitive(GTK_WIDGET(level2js_button), is_room_view(view)); 58 59 59 60 gtk_window_set_focus(GTK_WINDOW(g_app_dialog), GTK_WIDGET(command_entry)); -
gui/gladish.ui
re2b9461 rf42b4fb 1259 1259 <property name="group">app_level0</property> 1260 1260 <property name="receives_default">False</property> 1261 <property name="sensitive"> False</property>1261 <property name="sensitive">True</property> 1262 1262 <property name="visible">True</property> 1263 1263 </object> -
gui/world_tree.c
r4f7a90a rf42b4fb 268 268 gtk_widget_set_sensitive(GTK_WIDGET(level1_button), !running); 269 269 gtk_widget_set_sensitive(GTK_WIDGET(level2lash_button), !running); 270 gtk_widget_set_sensitive(GTK_WIDGET(level2js_button), !running && is_room_view(view)); 270 271 271 272 /* comparing pointers here is ok, because ladish_map_app_level_constant() was called by ladish_app_supervisor_get_app_properties() */
