aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/lib
diff options
context:
space:
mode:
authorJacek Antonelli2009-05-30 17:16:26 -0500
committerJacek Antonelli2009-05-30 19:12:37 -0500
commit499afbab7be4c4136eea0e1897319c3ac4e9799d (patch)
tree95e9de524994eae69b0dd88b8c6608d5f45d030c /linden/indra/lib
parentFixed end-of-line style for Info-Imprudence.plist. (diff)
parentSecond Life viewer sources 1.22.11 (diff)
downloadmeta-impy-499afbab7be4c4136eea0e1897319c3ac4e9799d.zip
meta-impy-499afbab7be4c4136eea0e1897319c3ac4e9799d.tar.gz
meta-impy-499afbab7be4c4136eea0e1897319c3ac4e9799d.tar.bz2
meta-impy-499afbab7be4c4136eea0e1897319c3ac4e9799d.tar.xz
Merged SL 1.22.11 into Imprudence 1.1 RC2.
Conflicts: linden/doc/contributions.txt linden/indra/cmake/APR.cmake linden/indra/cmake/CopyWinLibs.cmake linden/indra/cmake/LLKDU.cmake (removed) linden/indra/cmake/LLMedia.cmake linden/indra/cmake/OPENAL.cmake linden/indra/cmake/QuickTime.cmake (removed) linden/indra/develop.py linden/indra/lib/python/indra/base/llsd.py linden/indra/lib/python/indra/util/fastest_elementtree.py linden/indra/lib/python/indra/util/llmanifest.py linden/indra/lib/python/indra/util/named_query.py linden/indra/llaudio/CMakeLists.txt linden/indra/llaudio/audioengine.cpp linden/indra/llaudio/audioengine.h linden/indra/llaudio/audioengine_fmod.cpp linden/indra/llaudio/audioengine_fmod.h linden/indra/llaudio/audioengine_openal.cpp linden/indra/llaudio/audioengine_openal.h linden/indra/llaudio/listener_openal.cpp linden/indra/llaudio/listener_openal.h linden/indra/llaudio/windgen.h linden/indra/llcrashlogger/llcrashlogger.cpp linden/indra/llmedia/llmediaimplgstreamer.cpp linden/indra/llmedia/llmediaimplgstreamer_syms.cpp (removed) linden/indra/llmedia/llmediaimplgstreamer_syms.h (removed) linden/indra/llmessage/llcircuit.h linden/indra/llrender/llgl.cpp linden/indra/llrender/llrender.h linden/indra/llui/llfloater.cpp linden/indra/llui/lltexteditor.cpp linden/indra/llwindow/llwindowsdl.cpp linden/indra/mac_crash_logger/CMakeLists.txt linden/indra/mac_updater/CMakeLists.txt linden/indra/newview/CMakeLists.txt linden/indra/newview/English.lproj/InfoPlist.strings linden/indra/newview/Info-Imprudence.plist linden/indra/newview/installers/windows/installer_template.nsi linden/indra/newview/installers/windows/lang_de.nsi linden/indra/newview/installers/windows/lang_en-us.nsi linden/indra/newview/installers/windows/lang_ja.nsi linden/indra/newview/installers/windows/lang_ko.nsi linden/indra/newview/llappviewer.cpp linden/indra/newview/llaudiosourcevo.cpp linden/indra/newview/llfloaterabout.cpp linden/indra/newview/llfloaterhtml.cpp linden/indra/newview/llfloaterhtml.h linden/indra/newview/llfloaterinspect.cpp linden/indra/newview/llfloatersnapshot.cpp linden/indra/newview/llpanelgeneral.cpp linden/indra/newview/llpanelgeneral.h linden/indra/newview/llpanellogin.cpp linden/indra/newview/llpanelobject.cpp linden/indra/newview/llurlhistory.cpp linden/indra/newview/llviewermenu.cpp linden/indra/newview/llviewernetwork.cpp linden/indra/newview/llviewernetwork.h linden/indra/newview/llviewerobject.cpp linden/indra/newview/llviewerwindow.cpp linden/indra/newview/llvoavatar.cpp linden/indra/newview/res/viewerRes.rc linden/indra/newview/skins/default/xui/de/floater_env_settings.xml linden/indra/newview/skins/default/xui/de/floater_html.xml linden/indra/newview/skins/default/xui/de/floater_inspect.xml linden/indra/newview/skins/default/xui/de/floater_instant_message_group.xml linden/indra/newview/skins/default/xui/de/floater_lagmeter.xml linden/indra/newview/skins/default/xui/de/floater_lsl_guide.xml linden/indra/newview/skins/default/xui/de/floater_url_entry.xml linden/indra/newview/skins/default/xui/de/floater_water.xml linden/indra/newview/skins/default/xui/de/mime_types.xml linden/indra/newview/skins/default/xui/de/need_to_long.xml linden/indra/newview/skins/default/xui/de/need_to_translate.xml linden/indra/newview/skins/default/xui/de/need_to_update.xml linden/indra/newview/skins/default/xui/de/panel_friends.xml linden/indra/newview/skins/default/xui/de/panel_media_remote_expanded.xml linden/indra/newview/skins/default/xui/de/panel_preferences_voice.xml linden/indra/newview/skins/default/xui/de/panel_voice_controls.xml linden/indra/newview/skins/default/xui/de/panel_voice_enable.xml linden/indra/newview/skins/default/xui/de/panel_voice_options.xml linden/indra/newview/skins/default/xui/de/strings.xml linden/indra/newview/skins/default/xui/en-us/floater_chat_history.xml linden/indra/newview/skins/default/xui/en-us/floater_instant_message_ad_hoc.xml linden/indra/newview/skins/default/xui/en-us/floater_instant_message_group.xml linden/indra/newview/skins/default/xui/en-us/floater_lagmeter.xml linden/indra/newview/skins/default/xui/en-us/menu_pie_object.xml linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml linden/indra/newview/skins/default/xui/en-us/panel_audio_device.xml linden/indra/newview/skins/default/xui/en-us/panel_preferences_general.xml linden/indra/newview/skins/default/xui/en-us/panel_preferences_input.xml linden/indra/newview/skins/default/xui/en-us/panel_preferences_voice.xml linden/indra/newview/skins/default/xui/en-us/panel_voice_remote.xml linden/indra/newview/skins/default/xui/en-us/panel_voice_remote_expanded.xml linden/indra/newview/skins/default/xui/es/alerts.xml linden/indra/newview/skins/default/xui/es/floater_about_land.xml linden/indra/newview/skins/default/xui/es/floater_mute.xml linden/indra/newview/skins/default/xui/es/menu_viewer.xml linden/indra/newview/skins/default/xui/es/panel_group_land_money.xml linden/indra/newview/skins/default/xui/es/panel_preferences_general.xml linden/indra/newview/skins/default/xui/fr/alerts.xml linden/indra/newview/skins/default/xui/fr/floater_about.xml linden/indra/newview/skins/default/xui/fr/floater_about_land.xml linden/indra/newview/skins/default/xui/fr/floater_active_speakers.xml linden/indra/newview/skins/default/xui/fr/floater_animation_preview.xml linden/indra/newview/skins/default/xui/fr/floater_avatar_picker.xml linden/indra/newview/skins/default/xui/fr/floater_avatar_textures.xml linden/indra/newview/skins/default/xui/fr/floater_buy_contents.xml linden/indra/newview/skins/default/xui/fr/floater_buy_currency.xml linden/indra/newview/skins/default/xui/fr/floater_buy_land.xml linden/indra/newview/skins/default/xui/fr/floater_buy_object.xml linden/indra/newview/skins/default/xui/fr/floater_chat_history.xml linden/indra/newview/skins/default/xui/fr/floater_color_picker.xml linden/indra/newview/skins/default/xui/fr/floater_customize.xml linden/indra/newview/skins/default/xui/fr/floater_directory.xml linden/indra/newview/skins/default/xui/fr/floater_env_settings.xml linden/indra/newview/skins/default/xui/fr/floater_god_tools.xml linden/indra/newview/skins/default/xui/fr/floater_group_info.xml linden/indra/newview/skins/default/xui/fr/floater_hardware_settings.xml linden/indra/newview/skins/default/xui/fr/floater_html.xml linden/indra/newview/skins/default/xui/fr/floater_image_preview.xml linden/indra/newview/skins/default/xui/fr/floater_import.xml linden/indra/newview/skins/default/xui/fr/floater_instant_message.xml linden/indra/newview/skins/default/xui/fr/floater_instant_message_ad_hoc.xml linden/indra/newview/skins/default/xui/fr/floater_instant_message_group.xml linden/indra/newview/skins/default/xui/fr/floater_inventory.xml linden/indra/newview/skins/default/xui/fr/floater_inventory_item_properties.xml linden/indra/newview/skins/default/xui/fr/floater_inventory_view_finder.xml linden/indra/newview/skins/default/xui/fr/floater_joystick.xml linden/indra/newview/skins/default/xui/fr/floater_lagmeter.xml linden/indra/newview/skins/default/xui/fr/floater_land_holdings.xml linden/indra/newview/skins/default/xui/fr/floater_lsl_guide.xml linden/indra/newview/skins/default/xui/fr/floater_media_browser.xml linden/indra/newview/skins/default/xui/fr/floater_moveview.xml linden/indra/newview/skins/default/xui/fr/floater_mute.xml linden/indra/newview/skins/default/xui/fr/floater_mute_object.xml linden/indra/newview/skins/default/xui/fr/floater_name_description.xml linden/indra/newview/skins/default/xui/fr/floater_new_outfit_dialog.xml linden/indra/newview/skins/default/xui/fr/floater_openobject.xml linden/indra/newview/skins/default/xui/fr/floater_pay.xml linden/indra/newview/skins/default/xui/fr/floater_pay_object.xml linden/indra/newview/skins/default/xui/fr/floater_preferences.xml linden/indra/newview/skins/default/xui/fr/floater_preview_animation.xml linden/indra/newview/skins/default/xui/fr/floater_preview_gesture.xml linden/indra/newview/skins/default/xui/fr/floater_preview_notecard.xml linden/indra/newview/skins/default/xui/fr/floater_preview_notecard_keep_discard.xml linden/indra/newview/skins/default/xui/fr/floater_preview_sound.xml linden/indra/newview/skins/default/xui/fr/floater_price_for_listing.xml linden/indra/newview/skins/default/xui/fr/floater_region_info.xml linden/indra/newview/skins/default/xui/fr/floater_report_abuse.xml linden/indra/newview/skins/default/xui/fr/floater_report_bug.xml linden/indra/newview/skins/default/xui/fr/floater_script_ed_panel.xml linden/indra/newview/skins/default/xui/fr/floater_sell_land.xml linden/indra/newview/skins/default/xui/fr/floater_settings_debug.xml linden/indra/newview/skins/default/xui/fr/floater_skin_preview_template.xml linden/indra/newview/skins/default/xui/fr/floater_snapshot.xml linden/indra/newview/skins/default/xui/fr/floater_sound_preview.xml linden/indra/newview/skins/default/xui/fr/floater_telehub.xml linden/indra/newview/skins/default/xui/fr/floater_texture_ctrl.xml linden/indra/newview/skins/default/xui/fr/floater_tools.xml linden/indra/newview/skins/default/xui/fr/floater_top_objects.xml linden/indra/newview/skins/default/xui/fr/floater_url_entry.xml linden/indra/newview/skins/default/xui/fr/floater_windlight_options.xml linden/indra/newview/skins/default/xui/fr/floater_world_map.xml linden/indra/newview/skins/default/xui/fr/menu_inventory.xml linden/indra/newview/skins/default/xui/fr/menu_pie_avatar.xml linden/indra/newview/skins/default/xui/fr/menu_pie_land.xml linden/indra/newview/skins/default/xui/fr/menu_pie_self.xml linden/indra/newview/skins/default/xui/fr/menu_viewer.xml linden/indra/newview/skins/default/xui/fr/mime_types.xml linden/indra/newview/skins/default/xui/fr/notify.xml linden/indra/newview/skins/default/xui/fr/panel_audio.xml linden/indra/newview/skins/default/xui/fr/panel_audio_device.xml linden/indra/newview/skins/default/xui/fr/panel_avatar.xml linden/indra/newview/skins/default/xui/fr/panel_avatar_classified.xml linden/indra/newview/skins/default/xui/fr/panel_chat_bar.xml linden/indra/newview/skins/default/xui/fr/panel_classified.xml linden/indra/newview/skins/default/xui/fr/panel_event.xml linden/indra/newview/skins/default/xui/fr/panel_friends.xml linden/indra/newview/skins/default/xui/fr/panel_group.xml linden/indra/newview/skins/default/xui/fr/panel_group_finder.xml linden/indra/newview/skins/default/xui/fr/panel_group_general.xml linden/indra/newview/skins/default/xui/fr/panel_group_invite.xml linden/indra/newview/skins/default/xui/fr/panel_group_land_money.xml linden/indra/newview/skins/default/xui/fr/panel_group_notices.xml linden/indra/newview/skins/default/xui/fr/panel_group_roles.xml linden/indra/newview/skins/default/xui/fr/panel_group_voting.xml linden/indra/newview/skins/default/xui/fr/panel_groups.xml linden/indra/newview/skins/default/xui/fr/panel_login.xml linden/indra/newview/skins/default/xui/fr/panel_master_volume.xml linden/indra/newview/skins/default/xui/fr/panel_media_controls.xml linden/indra/newview/skins/default/xui/fr/panel_media_remote.xml linden/indra/newview/skins/default/xui/fr/panel_media_remote_expanded.xml linden/indra/newview/skins/default/xui/fr/panel_overlaybar.xml linden/indra/newview/skins/default/xui/fr/panel_place.xml linden/indra/newview/skins/default/xui/fr/panel_place_small.xml linden/indra/newview/skins/default/xui/fr/panel_preferences_audio.xml linden/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml linden/indra/newview/skins/default/xui/fr/panel_preferences_general.xml linden/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml linden/indra/newview/skins/default/xui/fr/panel_preferences_im.xml linden/indra/newview/skins/default/xui/fr/panel_preferences_input.xml linden/indra/newview/skins/default/xui/fr/panel_preferences_network.xml linden/indra/newview/skins/default/xui/fr/panel_preferences_popups.xml linden/indra/newview/skins/default/xui/fr/panel_preferences_voice.xml linden/indra/newview/skins/default/xui/fr/panel_preferences_web.xml linden/indra/newview/skins/default/xui/fr/panel_region_covenant.xml linden/indra/newview/skins/default/xui/fr/panel_region_debug.xml linden/indra/newview/skins/default/xui/fr/panel_region_estate.xml linden/indra/newview/skins/default/xui/fr/panel_region_general.xml linden/indra/newview/skins/default/xui/fr/panel_region_terrain.xml linden/indra/newview/skins/default/xui/fr/panel_scrolling_param.xml linden/indra/newview/skins/default/xui/fr/panel_speaker_controls.xml linden/indra/newview/skins/default/xui/fr/panel_status_bar.xml linden/indra/newview/skins/default/xui/fr/panel_toolbar.xml linden/indra/newview/skins/default/xui/fr/panel_voice_controls.xml linden/indra/newview/skins/default/xui/fr/panel_voice_enable.xml linden/indra/newview/skins/default/xui/fr/panel_voice_options.xml linden/indra/newview/skins/default/xui/fr/panel_voice_remote_expanded.xml linden/indra/newview/skins/default/xui/fr/role_actions.xml linden/indra/newview/skins/default/xui/fr/strings.xml linden/indra/newview/skins/default/xui/ja/floater_hardware_settings.xml linden/indra/newview/skins/default/xui/ja/floater_inspect.xml linden/indra/newview/skins/default/xui/ja/floater_instant_message_group.xml linden/indra/newview/skins/default/xui/ja/floater_lsl_guide.xml linden/indra/newview/skins/default/xui/ja/floater_media_browser.xml linden/indra/newview/skins/default/xui/ja/floater_mute_object.xml linden/indra/newview/skins/default/xui/ja/floater_url_entry.xml linden/indra/newview/skins/default/xui/ja/need_to_long.xml linden/indra/newview/skins/default/xui/ja/need_to_translate.xml linden/indra/newview/skins/default/xui/ja/need_to_update.xml linden/indra/newview/skins/default/xui/ja/panel_audio.xml linden/indra/newview/skins/default/xui/ja/panel_groups.xml linden/indra/newview/skins/default/xui/ja/panel_preferences_voice.xml linden/indra/newview/skins/default/xui/ja/panel_preferences_web.xml linden/indra/newview/skins/default/xui/ja/strings.xml linden/indra/newview/skins/default/xui/ko/need_to_long.xml linden/indra/newview/skins/default/xui/ko/need_to_translate.xml linden/indra/newview/skins/default/xui/ko/need_to_update.xml linden/indra/newview/skins/default/xui/pt/alerts.xml linden/indra/newview/skins/default/xui/pt/floater_about.xml linden/indra/newview/skins/default/xui/pt/floater_about_land.xml linden/indra/newview/skins/default/xui/pt/floater_animation_preview.xml linden/indra/newview/skins/default/xui/pt/floater_avatar_picker.xml linden/indra/newview/skins/default/xui/pt/floater_avatar_textures.xml linden/indra/newview/skins/default/xui/pt/floater_build_options.xml linden/indra/newview/skins/default/xui/pt/floater_buy_contents.xml linden/indra/newview/skins/default/xui/pt/floater_buy_currency.xml linden/indra/newview/skins/default/xui/pt/floater_buy_land.xml linden/indra/newview/skins/default/xui/pt/floater_buy_object.xml linden/indra/newview/skins/default/xui/pt/floater_chat_history.xml linden/indra/newview/skins/default/xui/pt/floater_color_picker.xml linden/indra/newview/skins/default/xui/pt/floater_customize.xml linden/indra/newview/skins/default/xui/pt/floater_directory.xml linden/indra/newview/skins/default/xui/pt/floater_gesture.xml linden/indra/newview/skins/default/xui/pt/floater_html.xml linden/indra/newview/skins/default/xui/pt/floater_im.xml linden/indra/newview/skins/default/xui/pt/floater_image_preview.xml linden/indra/newview/skins/default/xui/pt/floater_instant_message.xml linden/indra/newview/skins/default/xui/pt/floater_instant_message_ad_hoc.xml linden/indra/newview/skins/default/xui/pt/floater_inventory.xml linden/indra/newview/skins/default/xui/pt/floater_inventory_item_properties.xml linden/indra/newview/skins/default/xui/pt/floater_joystick.xml linden/indra/newview/skins/default/xui/pt/floater_land_holdings.xml linden/indra/newview/skins/default/xui/pt/floater_live_lsleditor.xml linden/indra/newview/skins/default/xui/pt/floater_mute.xml linden/indra/newview/skins/default/xui/pt/floater_new_outfit_dialog.xml linden/indra/newview/skins/default/xui/pt/floater_openobject.xml linden/indra/newview/skins/default/xui/pt/floater_pay.xml linden/indra/newview/skins/default/xui/pt/floater_pay_object.xml linden/indra/newview/skins/default/xui/pt/floater_postcard.xml linden/indra/newview/skins/default/xui/pt/floater_preview_animation.xml linden/indra/newview/skins/default/xui/pt/floater_preview_gesture.xml linden/indra/newview/skins/default/xui/pt/floater_preview_notecard.xml linden/indra/newview/skins/default/xui/pt/floater_preview_notecard_keep_discard.xml linden/indra/newview/skins/default/xui/pt/floater_report_abuse.xml linden/indra/newview/skins/default/xui/pt/floater_report_bug.xml linden/indra/newview/skins/default/xui/pt/floater_script_debug.xml linden/indra/newview/skins/default/xui/pt/floater_script_ed_panel.xml linden/indra/newview/skins/default/xui/pt/floater_snapshot.xml linden/indra/newview/skins/default/xui/pt/floater_texture_ctrl.xml linden/indra/newview/skins/default/xui/pt/floater_tools.xml linden/indra/newview/skins/default/xui/pt/floater_top_objects.xml linden/indra/newview/skins/default/xui/pt/floater_tos.xml linden/indra/newview/skins/default/xui/pt/floater_world_map.xml linden/indra/newview/skins/default/xui/pt/menu_inventory.xml linden/indra/newview/skins/default/xui/pt/menu_pie_avatar.xml linden/indra/newview/skins/default/xui/pt/menu_viewer.xml linden/indra/newview/skins/default/xui/pt/notify.xml linden/indra/newview/skins/default/xui/pt/panel_avatar.xml linden/indra/newview/skins/default/xui/pt/panel_avatar_classified.xml linden/indra/newview/skins/default/xui/pt/panel_chat_bar.xml linden/indra/newview/skins/default/xui/pt/panel_classified.xml linden/indra/newview/skins/default/xui/pt/panel_event.xml linden/indra/newview/skins/default/xui/pt/panel_group_general.xml linden/indra/newview/skins/default/xui/pt/panel_group_invite.xml linden/indra/newview/skins/default/xui/pt/panel_group_land_money.xml linden/indra/newview/skins/default/xui/pt/panel_group_notices.xml linden/indra/newview/skins/default/xui/pt/panel_group_roles.xml linden/indra/newview/skins/default/xui/pt/panel_group_voting.xml linden/indra/newview/skins/default/xui/pt/panel_login.xml linden/indra/newview/skins/default/xui/pt/panel_overlaybar.xml linden/indra/newview/skins/default/xui/pt/panel_place.xml linden/indra/newview/skins/default/xui/pt/panel_place_small.xml linden/indra/newview/skins/default/xui/pt/panel_preferences_audio.xml linden/indra/newview/skins/default/xui/pt/panel_preferences_chat.xml linden/indra/newview/skins/default/xui/pt/panel_preferences_general.xml linden/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml linden/indra/newview/skins/default/xui/pt/panel_preferences_im.xml linden/indra/newview/skins/default/xui/pt/panel_preferences_input.xml linden/indra/newview/skins/default/xui/pt/panel_preferences_network.xml linden/indra/newview/skins/default/xui/pt/panel_preferences_popups.xml linden/indra/newview/skins/default/xui/pt/panel_preferences_web.xml linden/indra/newview/skins/default/xui/pt/panel_region_covenant.xml linden/indra/newview/skins/default/xui/pt/panel_region_debug.xml linden/indra/newview/skins/default/xui/pt/panel_region_estate.xml linden/indra/newview/skins/default/xui/pt/panel_region_general.xml linden/indra/newview/skins/default/xui/pt/panel_status_bar.xml linden/indra/newview/skins/default/xui/pt/panel_toolbar.xml linden/indra/newview/skins/default/xui/pt/teleport_strings.xml linden/indra/newview/skins/default/xui/zh/floater_account_history.xml linden/indra/newview/skins/default/xui/zh/floater_god_tools.xml linden/indra/newview/skins/default/xui/zh/floater_html.xml linden/indra/newview/skins/default/xui/zh/floater_inspect.xml linden/indra/newview/skins/default/xui/zh/floater_inventory_view_finder.xml linden/indra/newview/skins/default/xui/zh/floater_preferences.xml linden/indra/newview/skins/default/xui/zh/floater_sell_land.xml linden/indra/newview/skins/default/xui/zh/floater_settings_debug.xml linden/indra/newview/skins/default/xui/zh/menu_pie_attachment.xml linden/indra/newview/skins/default/xui/zh/menu_pie_avatar.xml linden/indra/newview/skins/default/xui/zh/menu_pie_land.xml linden/indra/newview/skins/default/xui/zh/menu_pie_object.xml linden/indra/newview/skins/default/xui/zh/menu_pie_self.xml linden/indra/newview/skins/default/xui/zh/menu_viewer.xml linden/indra/newview/skins/default/xui/zh/need_to_translate.xml linden/indra/newview/skins/default/xui/zh/panel_account_details.xml linden/indra/newview/skins/default/xui/zh/panel_account_planning.xml linden/indra/newview/skins/default/xui/zh/panel_account_transactions.xml linden/indra/newview/skins/default/xui/zh/panel_avatar.xml linden/indra/newview/skins/default/xui/zh/panel_group.xml linden/indra/newview/skins/default/xui/zh/panel_group_finder.xml linden/indra/newview/skins/default/xui/zh/panel_group_general.xml linden/indra/newview/skins/default/xui/zh/panel_group_invite.xml linden/indra/newview/skins/default/xui/zh/panel_group_land_money.xml linden/indra/newview/skins/default/xui/zh/panel_group_notices.xml linden/indra/newview/skins/default/xui/zh/panel_group_roles.xml linden/indra/newview/skins/default/xui/zh/panel_group_voting.xml linden/indra/newview/skins/default/xui/zh/panel_preferences_audio.xml linden/indra/newview/skins/default/xui/zh/panel_preferences_chat.xml linden/indra/newview/skins/default/xui/zh/panel_preferences_im.xml linden/indra/newview/skins/default/xui/zh/panel_preferences_popups.xml linden/indra/newview/skins/default/xui/zh/panel_region_covenant.xml linden/indra/newview/skins/default/xui/zh/strings.xml linden/indra/newview/skins/default/xui/zh/strings_long.xml linden/indra/newview/skins/silver/xui/en-us/floater_about_land.xml linden/indra/newview/skins/silver/xui/en-us/panel_status_bar.xml linden/indra/newview/viewer_manifest.py linden/indra/win_updater/updater.cpp linden/install.xml
Diffstat (limited to 'linden/indra/lib')
-rw-r--r--linden/indra/lib/python/indra/__init__.py2
-rw-r--r--linden/indra/lib/python/indra/base/__init__.py2
-rw-r--r--linden/indra/lib/python/indra/base/config.py2
-rw-r--r--linden/indra/lib/python/indra/base/lllog.py4
-rw-r--r--linden/indra/lib/python/indra/base/llsd.py13
-rw-r--r--linden/indra/lib/python/indra/base/lluuid.py2
-rw-r--r--linden/indra/lib/python/indra/base/metrics.py2
-rw-r--r--linden/indra/lib/python/indra/ipc/__init__.py2
-rw-r--r--linden/indra/lib/python/indra/ipc/compatibility.py2
-rw-r--r--linden/indra/lib/python/indra/ipc/llmessage.py4
-rw-r--r--linden/indra/lib/python/indra/ipc/llsdhttp.py2
-rw-r--r--linden/indra/lib/python/indra/ipc/mysql_pool.py2
-rw-r--r--linden/indra/lib/python/indra/ipc/russ.py2
-rw-r--r--linden/indra/lib/python/indra/ipc/saranwrap.py651
-rw-r--r--linden/indra/lib/python/indra/ipc/servicebuilder.py2
-rw-r--r--linden/indra/lib/python/indra/ipc/tokenstream.py2
-rw-r--r--linden/indra/lib/python/indra/ipc/webdav.py2
-rw-r--r--linden/indra/lib/python/indra/ipc/xml_rpc.py2
-rw-r--r--linden/indra/lib/python/indra/util/__init__.py2
-rw-r--r--linden/indra/lib/python/indra/util/fastest_elementtree.py2
-rw-r--r--linden/indra/lib/python/indra/util/helpformatter.py2
-rw-r--r--linden/indra/lib/python/indra/util/iterators.py63
-rwxr-xr-xlinden/indra/lib/python/indra/util/iterators_test.py72
-rw-r--r--linden/indra/lib/python/indra/util/llmanifest.py12
-rwxr-xr-xlinden/indra/lib/python/indra/util/llperformance.py158
-rw-r--r--linden/indra/lib/python/indra/util/llsubprocess.py2
-rw-r--r--linden/indra/lib/python/indra/util/llversion.py2
-rw-r--r--linden/indra/lib/python/indra/util/named_query.py6
-rw-r--r--linden/indra/lib/python/indra/util/shutil2.py2
-rwxr-xr-xlinden/indra/lib/python/indra/util/simperf_host_xml_parser.py338
-rwxr-xr-xlinden/indra/lib/python/indra/util/simperf_oprof_interface.py160
-rwxr-xr-xlinden/indra/lib/python/indra/util/simperf_proc_interface.py164
-rw-r--r--linden/indra/lib/python/indra/util/term.py2
33 files changed, 993 insertions, 694 deletions
diff --git a/linden/indra/lib/python/indra/__init__.py b/linden/indra/lib/python/indra/__init__.py
index b435e57..9daab34 100644
--- a/linden/indra/lib/python/indra/__init__.py
+++ b/linden/indra/lib/python/indra/__init__.py
@@ -4,7 +4,7 @@
4 4
5$LicenseInfo:firstyear=2006&license=internal$ 5$LicenseInfo:firstyear=2006&license=internal$
6 6
7Copyright (c) 2006-2008, Linden Research, Inc. 7Copyright (c) 2006-2009, Linden Research, Inc.
8 8
9The following source code is PROPRIETARY AND CONFIDENTIAL. Use of 9The following source code is PROPRIETARY AND CONFIDENTIAL. Use of
10this source code is governed by the Linden Lab Source Code Disclosure 10this source code is governed by the Linden Lab Source Code Disclosure
diff --git a/linden/indra/lib/python/indra/base/__init__.py b/linden/indra/lib/python/indra/base/__init__.py
index 46eabd7..2904fd3 100644
--- a/linden/indra/lib/python/indra/base/__init__.py
+++ b/linden/indra/lib/python/indra/base/__init__.py
@@ -4,7 +4,7 @@
4 4
5$LicenseInfo:firstyear=2007&license=mit$ 5$LicenseInfo:firstyear=2007&license=mit$
6 6
7Copyright (c) 2007-2008, Linden Research, Inc. 7Copyright (c) 2007-2009, Linden Research, Inc.
8 8
9Permission is hereby granted, free of charge, to any person obtaining a copy 9Permission is hereby granted, free of charge, to any person obtaining a copy
10of this software and associated documentation files (the "Software"), to deal 10of this software and associated documentation files (the "Software"), to deal
diff --git a/linden/indra/lib/python/indra/base/config.py b/linden/indra/lib/python/indra/base/config.py
index 9c37ecf..d6866fd 100644
--- a/linden/indra/lib/python/indra/base/config.py
+++ b/linden/indra/lib/python/indra/base/config.py
@@ -4,7 +4,7 @@
4 4
5$LicenseInfo:firstyear=2006&license=mit$ 5$LicenseInfo:firstyear=2006&license=mit$
6 6
7Copyright (c) 2006-2008, Linden Research, Inc. 7Copyright (c) 2006-2009, Linden Research, Inc.
8 8
9Permission is hereby granted, free of charge, to any person obtaining a copy 9Permission is hereby granted, free of charge, to any person obtaining a copy
10of this software and associated documentation files (the "Software"), to deal 10of this software and associated documentation files (the "Software"), to deal
diff --git a/linden/indra/lib/python/indra/base/lllog.py b/linden/indra/lib/python/indra/base/lllog.py
index 99c50ef..31000fc 100644
--- a/linden/indra/lib/python/indra/base/lllog.py
+++ b/linden/indra/lib/python/indra/base/lllog.py
@@ -4,7 +4,7 @@
4 4
5$LicenseInfo:firstyear=2008&license=mit$ 5$LicenseInfo:firstyear=2008&license=mit$
6 6
7Copyright (c) 2008, Linden Research, Inc. 7Copyright (c) 2008-2009, Linden Research, Inc.
8 8
9Permission is hereby granted, free of charge, to any person obtaining a copy 9Permission is hereby granted, free of charge, to any person obtaining a copy
10of this software and associated documentation files (the "Software"), to deal 10of this software and associated documentation files (the "Software"), to deal
@@ -59,7 +59,7 @@ class Logger(object):
59 return self._sequence 59 return self._sequence
60 60
61 def log(self, msg, llsd): 61 def log(self, msg, llsd):
62 payload = 'LLLOGMESSAGE (%d) %s %s' % (self.next(), msg, 62 payload = 'INFO: log: LLLOGMESSAGE (%d) %s %s' % (self.next(), msg,
63 format_notation(llsd)) 63 format_notation(llsd))
64 syslog.syslog(payload) 64 syslog.syslog(payload)
65 65
diff --git a/linden/indra/lib/python/indra/base/llsd.py b/linden/indra/lib/python/indra/base/llsd.py
index e6141b6..821a20b 100644
--- a/linden/indra/lib/python/indra/base/llsd.py
+++ b/linden/indra/lib/python/indra/base/llsd.py
@@ -4,7 +4,7 @@
4 4
5$LicenseInfo:firstyear=2006&license=mit$ 5$LicenseInfo:firstyear=2006&license=mit$
6 6
7Copyright (c) 2006-2008, Linden Research, Inc. 7Copyright (c) 2006-2009, Linden Research, Inc.
8 8
9Permission is hereby granted, free of charge, to any person obtaining a copy 9Permission is hereby granted, free of charge, to any person obtaining a copy
10of this software and associated documentation files (the "Software"), to deal 10of this software and associated documentation files (the "Software"), to deal
@@ -36,13 +36,10 @@ import re
36from indra.util.fastest_elementtree import ElementTreeError, fromstring 36from indra.util.fastest_elementtree import ElementTreeError, fromstring
37from indra.base import lluuid 37from indra.base import lluuid
38 38
39# cllsd.c in server/server-1.25 has memory leaks, 39try:
40# so disabling cllsd for now 40 import cllsd
41#try: 41except ImportError:
42# import cllsd 42 cllsd = None
43#except ImportError:
44# cllsd = None
45cllsd = None
46 43
47int_regex = re.compile(r"[-+]?\d+") 44int_regex = re.compile(r"[-+]?\d+")
48real_regex = re.compile(r"[-+]?(\d+(\.\d*)?|\d*\.\d+)([eE][-+]?\d+)?") 45real_regex = re.compile(r"[-+]?(\d+(\.\d*)?|\d*\.\d+)([eE][-+]?\d+)?")
diff --git a/linden/indra/lib/python/indra/base/lluuid.py b/linden/indra/lib/python/indra/base/lluuid.py
index 0756889..aceea29 100644
--- a/linden/indra/lib/python/indra/base/lluuid.py
+++ b/linden/indra/lib/python/indra/base/lluuid.py
@@ -4,7 +4,7 @@
4 4
5$LicenseInfo:firstyear=2004&license=mit$ 5$LicenseInfo:firstyear=2004&license=mit$
6 6
7Copyright (c) 2004-2008, Linden Research, Inc. 7Copyright (c) 2004-2009, Linden Research, Inc.
8 8
9Permission is hereby granted, free of charge, to any person obtaining a copy 9Permission is hereby granted, free of charge, to any person obtaining a copy
10of this software and associated documentation files (the "Software"), to deal 10of this software and associated documentation files (the "Software"), to deal
diff --git a/linden/indra/lib/python/indra/base/metrics.py b/linden/indra/lib/python/indra/base/metrics.py
index 04e6286..8f2a85c 100644
--- a/linden/indra/lib/python/indra/base/metrics.py
+++ b/linden/indra/lib/python/indra/base/metrics.py
@@ -6,7 +6,7 @@
6 6
7$LicenseInfo:firstyear=2007&license=mit$ 7$LicenseInfo:firstyear=2007&license=mit$
8 8
9Copyright (c) 2007-2008, Linden Research, Inc. 9Copyright (c) 2007-2009, Linden Research, Inc.
10 10
11Permission is hereby granted, free of charge, to any person obtaining a copy 11Permission is hereby granted, free of charge, to any person obtaining a copy
12of this software and associated documentation files (the "Software"), to deal 12of this software and associated documentation files (the "Software"), to deal
diff --git a/linden/indra/lib/python/indra/ipc/__init__.py b/linden/indra/lib/python/indra/ipc/__init__.py
index fc1e654..302bbf4 100644
--- a/linden/indra/lib/python/indra/ipc/__init__.py
+++ b/linden/indra/lib/python/indra/ipc/__init__.py
@@ -4,7 +4,7 @@
4 4
5$LicenseInfo:firstyear=2006&license=mit$ 5$LicenseInfo:firstyear=2006&license=mit$
6 6
7Copyright (c) 2006-2008, Linden Research, Inc. 7Copyright (c) 2006-2009, Linden Research, Inc.
8 8
9Permission is hereby granted, free of charge, to any person obtaining a copy 9Permission is hereby granted, free of charge, to any person obtaining a copy
10of this software and associated documentation files (the "Software"), to deal 10of this software and associated documentation files (the "Software"), to deal
diff --git a/linden/indra/lib/python/indra/ipc/compatibility.py b/linden/indra/lib/python/indra/ipc/compatibility.py
index 07a4066..b9045c2 100644
--- a/linden/indra/lib/python/indra/ipc/compatibility.py
+++ b/linden/indra/lib/python/indra/ipc/compatibility.py
@@ -4,7 +4,7 @@
4 4
5$LicenseInfo:firstyear=2007&license=mit$ 5$LicenseInfo:firstyear=2007&license=mit$
6 6
7Copyright (c) 2007-2008, Linden Research, Inc. 7Copyright (c) 2007-2009, Linden Research, Inc.
8 8
9Permission is hereby granted, free of charge, to any person obtaining a copy 9Permission is hereby granted, free of charge, to any person obtaining a copy
10of this software and associated documentation files (the "Software"), to deal 10of this software and associated documentation files (the "Software"), to deal
diff --git a/linden/indra/lib/python/indra/ipc/llmessage.py b/linden/indra/lib/python/indra/ipc/llmessage.py
index 446679d..6161bad 100644
--- a/linden/indra/lib/python/indra/ipc/llmessage.py
+++ b/linden/indra/lib/python/indra/ipc/llmessage.py
@@ -4,7 +4,7 @@
4 4
5$LicenseInfo:firstyear=2007&license=mit$ 5$LicenseInfo:firstyear=2007&license=mit$
6 6
7Copyright (c) 2007-2008, Linden Research, Inc. 7Copyright (c) 2007-2009, Linden Research, Inc.
8 8
9Permission is hereby granted, free of charge, to any person obtaining a copy 9Permission is hereby granted, free of charge, to any person obtaining a copy
10of this software and associated documentation files (the "Software"), to deal 10of this software and associated documentation files (the "Software"), to deal
@@ -88,7 +88,7 @@ class Message:
88 UDPDEPRECATED = "UDPDeprecated" 88 UDPDEPRECATED = "UDPDeprecated"
89 UDPBLACKLISTED = "UDPBlackListed" 89 UDPBLACKLISTED = "UDPBlackListed"
90 deprecations = [ NOTDEPRECATED, UDPDEPRECATED, UDPBLACKLISTED, DEPRECATED ] 90 deprecations = [ NOTDEPRECATED, UDPDEPRECATED, UDPBLACKLISTED, DEPRECATED ]
91 # in order of increasing deprecation 91 # in order of increasing deprecation
92 92
93 def __init__(self, name, number, priority, trust, coding): 93 def __init__(self, name, number, priority, trust, coding):
94 self.name = name 94 self.name = name
diff --git a/linden/indra/lib/python/indra/ipc/llsdhttp.py b/linden/indra/lib/python/indra/ipc/llsdhttp.py
index ed64899..cbe8ee1 100644
--- a/linden/indra/lib/python/indra/ipc/llsdhttp.py
+++ b/linden/indra/lib/python/indra/ipc/llsdhttp.py
@@ -4,7 +4,7 @@
4 4
5$LicenseInfo:firstyear=2006&license=mit$ 5$LicenseInfo:firstyear=2006&license=mit$
6 6
7Copyright (c) 2006-2008, Linden Research, Inc. 7Copyright (c) 2006-2009, Linden Research, Inc.
8 8
9Permission is hereby granted, free of charge, to any person obtaining a copy 9Permission is hereby granted, free of charge, to any person obtaining a copy
10of this software and associated documentation files (the "Software"), to deal 10of this software and associated documentation files (the "Software"), to deal
diff --git a/linden/indra/lib/python/indra/ipc/mysql_pool.py b/linden/indra/lib/python/indra/ipc/mysql_pool.py
index 25a66cf..e5855a3 100644
--- a/linden/indra/lib/python/indra/ipc/mysql_pool.py
+++ b/linden/indra/lib/python/indra/ipc/mysql_pool.py
@@ -4,7 +4,7 @@
4 4
5$LicenseInfo:firstyear=2007&license=mit$ 5$LicenseInfo:firstyear=2007&license=mit$
6 6
7Copyright (c) 2007-2008, Linden Research, Inc. 7Copyright (c) 2007-2009, Linden Research, Inc.
8 8
9Permission is hereby granted, free of charge, to any person obtaining a copy 9Permission is hereby granted, free of charge, to any person obtaining a copy
10of this software and associated documentation files (the "Software"), to deal 10of this software and associated documentation files (the "Software"), to deal
diff --git a/linden/indra/lib/python/indra/ipc/russ.py b/linden/indra/lib/python/indra/ipc/russ.py
index fbb1777..35d8afb 100644
--- a/linden/indra/lib/python/indra/ipc/russ.py
+++ b/linden/indra/lib/python/indra/ipc/russ.py
@@ -11,7 +11,7 @@ implementations section.
11 11
12$LicenseInfo:firstyear=2007&license=mit$ 12$LicenseInfo:firstyear=2007&license=mit$
13 13
14Copyright (c) 2007-2008, Linden Research, Inc. 14Copyright (c) 2007-2009, Linden Research, Inc.
15 15
16Permission is hereby granted, free of charge, to any person obtaining a copy 16Permission is hereby granted, free of charge, to any person obtaining a copy
17of this software and associated documentation files (the "Software"), to deal 17of this software and associated documentation files (the "Software"), to deal
diff --git a/linden/indra/lib/python/indra/ipc/saranwrap.py b/linden/indra/lib/python/indra/ipc/saranwrap.py
deleted file mode 100644
index e0205bf..0000000
--- a/linden/indra/lib/python/indra/ipc/saranwrap.py
+++ /dev/null
@@ -1,651 +0,0 @@
1"""\
2@file saranwrap.py
3@author Phoenix
4@date 2007-07-13
5@brief A simple, pickle based rpc mechanism which reflects python
6objects and callables.
7
8$LicenseInfo:firstyear=2007&license=mit$
9
10Copyright (c) 2007-2008, Linden Research, Inc.
11
12Permission is hereby granted, free of charge, to any person obtaining a copy
13of this software and associated documentation files (the "Software"), to deal
14in the Software without restriction, including without limitation the rights
15to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16copies of the Software, and to permit persons to whom the Software is
17furnished to do so, subject to the following conditions:
18
19The above copyright notice and this permission notice shall be included in
20all copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28THE SOFTWARE.
29$/LicenseInfo$
30
31This file provides classes and exceptions used for simple python level
32remote procedure calls. This is achieved by intercepting the basic
33getattr and setattr calls in a client proxy, which commnicates those
34down to the server which will dispatch them to objects in it's process
35space.
36
37The basic protocol to get and set attributes is for the client proxy
38to issue the command:
39
40getattr $id $name
41setattr $id $name $value
42
43getitem $id $item
44setitem $id $item $value
45eq $id $rhs
46del $id
47
48When the get returns a callable, the client proxy will provide a
49callable proxy which will invoke a remote procedure call. The command
50issued from the callable proxy to server is:
51
52call $id $name $args $kwargs
53
54If the client supplies an id of None, then the get/set/call is applied
55to the object(s) exported from the server.
56
57The server will parse the get/set/call, take the action indicated, and
58return back to the caller one of:
59
60value $val
61callable
62object $id
63exception $excp
64
65To handle object expiration, the proxy will instruct the rpc server to
66discard objects which are no longer in use. This is handled by
67catching proxy deletion and sending the command:
68
69del $id
70
71The server will handle this by removing clearing it's own internal
72references. This does not mean that the object will necessarily be
73cleaned from the server, but no artificial references will remain
74after successfully completing. On completion, the server will return
75one of:
76
77value None
78exception $excp
79
80The server also accepts a special command for debugging purposes:
81
82status
83
84Which will be intercepted by the server to write back:
85
86status {...}
87
88The wire protocol is to pickle the Request class in this file. The
89request class is basically an action and a map of parameters'
90"""
91
92import os
93import cPickle
94import struct
95import sys
96
97try:
98 set = set
99 frozenset = frozenset
100except NameError:
101 from sets import Set as set, ImmutableSet as frozenset
102
103from eventlet.processes import Process
104from eventlet import api
105
106#
107# debugging hooks
108#
109_g_debug_mode = False
110if _g_debug_mode:
111 import traceback
112
113def pythonpath_sync():
114 """
115@brief apply the current sys.path to the environment variable PYTHONPATH, so that child processes have the same paths as the caller does.
116"""
117 pypath = os.pathsep.join(sys.path)
118 os.environ['PYTHONPATH'] = pypath
119
120def wrap(obj, dead_callback = None):
121 """
122@brief wrap in object in another process through a saranwrap proxy
123@param object The object to wrap.
124@param dead_callback A callable to invoke if the process exits."""
125
126 if type(obj).__name__ == 'module':
127 return wrap_module(obj.__name__, dead_callback)
128 pythonpath_sync()
129 p = Process('python', [__file__, '--child'], dead_callback)
130 prox = Proxy(p, p)
131 prox.obj = obj
132 return prox.obj
133
134def wrap_module(fqname, dead_callback = None):
135 """
136@brief wrap a module in another process through a saranwrap proxy
137@param fqname The fully qualified name of the module.
138@param dead_callback A callable to invoke if the process exits."""
139 pythonpath_sync()
140 global _g_debug_mode
141 if _g_debug_mode:
142 p = Process('python', [__file__, '--module', fqname, '--logfile', '/tmp/saranwrap.log'], dead_callback)
143 else:
144 p = Process('python', [__file__, '--module', fqname,], dead_callback)
145 prox = Proxy(p, p)
146 return prox
147
148def status(proxy):
149 """
150@brief get the status from the server through a proxy
151@param proxy a saranwrap.Proxy object connected to a server."""
152 _write_request(Request('status', {}), proxy.__local_dict['_out'])
153 return _read_response(None, None, proxy.__local_dict['_in'], proxy.__local_dict['_out'], None)
154
155class BadResponse(Exception):
156 """"This exception is raised by an saranwrap client when it could
157 parse but cannot understand the response from the server."""
158 pass
159
160class BadRequest(Exception):
161 """"This exception is raised by a saranwrap server when it could parse
162 but cannot understand the response from the server."""
163 pass
164
165class UnrecoverableError(Exception):
166 pass
167
168class Request(object):
169 "@brief A wrapper class for proxy requests to the server."
170 def __init__(self, action, param):
171 self._action = action
172 self._param = param
173 def __str__(self):
174 return "Request `"+self._action+"` "+str(self._param)
175 def __getitem__(self, name):
176 return self._param[name]
177 def action(self):
178 return self._action
179
180def _read_lp_hunk(stream):
181 len_bytes = stream.read(4)
182 length = struct.unpack('I', len_bytes)[0]
183 body = stream.read(length)
184 return body
185
186def _read_response(id, attribute, input, output, dead_list):
187 """@brief local helper method to read respones from the rpc server."""
188 try:
189 str = _read_lp_hunk(input)
190 _prnt(`str`)
191 response = cPickle.loads(str)
192 except AttributeError, e:
193 raise UnrecoverableError(e)
194 _prnt("response: %s" % response)
195 if response[0] == 'value':
196 return response[1]
197 elif response[0] == 'callable':
198 return CallableProxy(id, attribute, input, output, dead_list)
199 elif response[0] == 'object':
200 return ObjectProxy(input, output, response[1], dead_list)
201 elif response[0] == 'exception':
202 exp = response[1]
203 raise exp
204 else:
205 raise BadResponse(response[0])
206
207def _write_lp_hunk(stream, hunk):
208 write_length = struct.pack('I', len(hunk))
209 stream.write(write_length + hunk)
210 if hasattr(stream, 'flush'):
211 stream.flush()
212
213def _write_request(param, output):
214 _prnt("request: %s" % param)
215 str = cPickle.dumps(param)
216 _write_lp_hunk(output, str)
217
218def _is_local(attribute):
219 "Return true if the attribute should be handled locally"
220# return attribute in ('_in', '_out', '_id', '__getattribute__', '__setattr__', '__dict__')
221 # good enough for now. :)
222 if '__local_dict' in attribute:
223 return True
224 return False
225
226def _prnt(message):
227 global _g_debug_mode
228 if _g_debug_mode:
229 print message
230
231_g_logfile = None
232def _log(message):
233 global _g_logfile
234 if _g_logfile:
235 _g_logfile.write(str(os.getpid()) + ' ' + message)
236 _g_logfile.write('\n')
237 _g_logfile.flush()
238
239def _unmunge_attr_name(name):
240 """ Sometimes attribute names come in with classname prepended, not sure why.
241 This function removes said classname, because we're huge hackers and we didn't
242 find out what the true right thing to do is. *FIX: find out. """
243 if(name.startswith('_Proxy')):
244 name = name[len('_Proxy'):]
245 if(name.startswith('_ObjectProxy')):
246 name = name[len('_ObjectProxy'):]
247 return name
248
249
250class Proxy(object):
251 """\
252@class Proxy
253@brief This class wraps a remote python process, presumably available
254in an instance of an Server.
255
256This is the class you will typically use as a client to a child
257process. Simply instantiate one around a file-like interface and start
258calling methods on the thing that is exported. The dir() builtin is
259not supported, so you have to know what has been exported.
260"""
261 def __init__(self, input, output, dead_list = None):
262 """\
263@param input a file-like object which supports read().
264@param output a file-like object which supports write() and flush().
265@param id an identifier for the remote object. humans do not provide this.
266"""
267 # default dead_list inside the function because all objects in method
268 # argument lists are init-ed only once globally
269 if dead_list is None:
270 dead_list = set()
271 #_prnt("Proxy::__init__")
272 self.__local_dict = dict(
273 _in = input,
274 _out = output,
275 _dead_list = dead_list,
276 _id = None)
277
278 def __getattribute__(self, attribute):
279 #_prnt("Proxy::__getattr__: %s" % attribute)
280 if _is_local(attribute):
281 # call base class getattribute so we actually get the local variable
282 attribute = _unmunge_attr_name(attribute)
283 return super(Proxy, self).__getattribute__(attribute)
284 else:
285 my_in = self.__local_dict['_in']
286 my_out = self.__local_dict['_out']
287 my_id = self.__local_dict['_id']
288
289 _dead_list = self.__local_dict['_dead_list']
290 for dead_object in _dead_list.copy():
291 request = Request('del', {'id':dead_object})
292 _write_request(request, my_out)
293 response = _read_response(my_id, attribute, my_in, my_out, _dead_list)
294 _dead_list.remove(dead_object)
295
296 # Pass all public attributes across to find out if it is
297 # callable or a simple attribute.
298 request = Request('getattr', {'id':my_id, 'attribute':attribute})
299 _write_request(request, my_out)
300 return _read_response(my_id, attribute, my_in, my_out, _dead_list)
301
302 def __setattr__(self, attribute, value):
303 #_prnt("Proxy::__setattr__: %s" % attribute)
304 if _is_local(attribute):
305 # It must be local to this actual object, so we have to apply
306 # it to the dict in a roundabout way
307 attribute = _unmunge_attr_name(attribute)
308 super(Proxy, self).__getattribute__('__dict__')[attribute]=value
309 else:
310 my_in = self.__local_dict['_in']
311 my_out = self.__local_dict['_out']
312 my_id = self.__local_dict['_id']
313 _dead_list = self.__local_dict['_dead_list']
314 # Pass the set attribute across
315 request = Request('setattr', {'id':my_id, 'attribute':attribute, 'value':value})
316 _write_request(request, my_out)
317 return _read_response(my_id, attribute, my_in, my_out, _dead_list)
318
319class ObjectProxy(Proxy):
320 """\
321@class ObjectProxy
322@brief This class wraps a remote object in the Server
323
324This class will be created during normal operation, and users should
325not need to deal with this class directly."""
326
327 def __init__(self, input, output, id, dead_list):
328 """\
329@param input a file-like object which supports read().
330@param output a file-like object which supports write() and flush().
331@param id an identifier for the remote object. humans do not provide this.
332"""
333 Proxy.__init__(self, input, output, dead_list)
334 self.__local_dict['_id'] = id
335 #_prnt("ObjectProxy::__init__ %s" % self._id)
336
337 def __del__(self):
338 my_id = self.__local_dict['_id']
339 _prnt("ObjectProxy::__del__ %s" % my_id)
340 self.__local_dict['_dead_list'].add(my_id)
341
342 def __getitem__(self, key):
343 my_in = self.__local_dict['_in']
344 my_out = self.__local_dict['_out']
345 my_id = self.__local_dict['_id']
346 _dead_list = self.__local_dict['_dead_list']
347 request = Request('getitem', {'id':my_id, 'key':key})
348 _write_request(request, my_out)
349 return _read_response(my_id, key, my_in, my_out, _dead_list)
350
351 def __setitem__(self, key, value):
352 my_in = self.__local_dict['_in']
353 my_out = self.__local_dict['_out']
354 my_id = self.__local_dict['_id']
355 _dead_list = self.__local_dict['_dead_list']
356 request = Request('setitem', {'id':my_id, 'key':key, 'value':value})
357 _write_request(request, my_out)
358 return _read_response(my_id, key, my_in, my_out, _dead_list)
359
360 def __eq__(self, rhs):
361 my_in = self.__local_dict['_in']
362 my_out = self.__local_dict['_out']
363 my_id = self.__local_dict['_id']
364 _dead_list = self.__local_dict['_dead_list']
365 request = Request('eq', {'id':my_id, 'rhs':rhs.__local_dict['_id']})
366 _write_request(request, my_out)
367 return _read_response(my_id, None, my_in, my_out, _dead_list)
368
369 def __repr__(self):
370 # apparently repr(obj) skips the whole getattribute thing and just calls __repr__
371 # directly. Therefore we just pass it through the normal call pipeline, and
372 # tack on a little header so that you can tell it's an object proxy.
373 val = self.__repr__()
374 return "saran:%s" % val
375
376 def __str__(self):
377 # see description for __repr__, because str(obj) works the same. We don't
378 # tack anything on to the return value here because str values are used as data.
379 return self.__str__()
380
381 def __len__(self):
382 # see description for __repr__, len(obj) is the same. Unfortunately, __len__ is also
383 # used when determining whether an object is boolean or not, e.g. if proxied_object:
384 return self.__len__()
385
386def proxied_type(self):
387 if type(self) is not ObjectProxy:
388 return type(self)
389
390 my_in = self.__local_dict['_in']
391 my_out = self.__local_dict['_out']
392 my_id = self.__local_dict['_id']
393 request = Request('type', {'id':my_id})
394 _write_request(request, my_out)
395 # dead list can be none because we know the result will always be
396 # a value and not an ObjectProxy itself
397 return _read_response(my_id, None, my_in, my_out, None)
398
399class CallableProxy(object):
400 """\
401@class CallableProxy
402@brief This class wraps a remote function in the Server
403
404This class will be created by an Proxy during normal operation,
405and users should not need to deal with this class directly."""
406
407 def __init__(self, object_id, name, input, output, dead_list):
408 #_prnt("CallableProxy::__init__: %s, %s" % (object_id, name))
409 self._object_id = object_id
410 self._name = name
411 self._in = input
412 self._out = output
413 self._dead_list = dead_list
414
415 def __call__(self, *args, **kwargs):
416 #_prnt("CallableProxy::__call__: %s, %s" % (args, kwargs))
417
418 # Pass the call across. We never build a callable without
419 # having already checked if the method starts with '_' so we
420 # can safely pass this one to the remote object.
421 #_prnt("calling %s %s" % (self._object_id, self._name)
422 request = Request('call', {'id':self._object_id, 'name':self._name, 'args':args, 'kwargs':kwargs})
423 _write_request(request, self._out)
424 return _read_response(self._object_id, self._name, self._in, self._out, self._dead_list)
425
426class Server(object):
427 def __init__(self, input, output, export):
428 """\
429@param input a file-like object which supports read().
430@param output a file-like object which supports write() and flush().
431@param export an object, function, or map which is exported to clients
432when the id is None."""
433 #_log("Server::__init__")
434 self._in = input
435 self._out = output
436 self._export = export
437 self._next_id = 1
438 self._objects = {}
439
440 def handle_status(self, object, req):
441 return {
442 'object_count':len(self._objects),
443 'next_id':self._next_id,
444 'pid':os.getpid()}
445
446 def handle_getattr(self, object, req):
447 try:
448 return getattr(object, req['attribute'])
449 except AttributeError, e:
450 if hasattr(object, "__getitem__"):
451 return object[req['attribute']]
452 else:
453 raise e
454 #_log('getattr: %s' % str(response))
455
456 def handle_setattr(self, object, req):
457 try:
458 return setattr(object, req['attribute'], req['value'])
459 except AttributeError, e:
460 if hasattr(object, "__setitem__"):
461 return object.__setitem__(req['attribute'], req['value'])
462 else:
463 raise e
464
465 def handle_getitem(self, object, req):
466 return object[req['key']]
467
468 def handle_setitem(self, object, req):
469 object[req['key']] = req['value']
470 return None # *TODO figure out what the actual return value of __setitem__ should be
471
472 def handle_eq(self, object, req):
473 #_log("__eq__ %s %s" % (object, req))
474 rhs = None
475 try:
476 rhs = self._objects[req['rhs']]
477 except KeyError, e:
478 return False
479 return (object == rhs)
480
481 def handle_call(self, object, req):
482 #_log("calling %s " % (req['name']))
483 try:
484 fn = getattr(object, req['name'])
485 except AttributeError, e:
486 if hasattr(object, "__setitem__"):
487 fn = object[req['name']]
488 else:
489 raise e
490
491 return fn(*req['args'],**req['kwargs'])
492
493 def handle_del(self, object, req):
494 id = req['id']
495 _log("del %s from %s" % (id, self._objects))
496
497 # *TODO what does __del__ actually return?
498 del self._objects[id]
499 return None
500
501 def handle_type(self, object, req):
502 return type(object)
503
504 def loop(self):
505 """@brief Loop forever and respond to all requests."""
506 _log("Server::loop")
507 while True:
508 try:
509 try:
510 str = _read_lp_hunk(self._in)
511 except EOFError:
512 sys.exit(0) # normal exit
513 request = cPickle.loads(str)
514 _log("request: %s (%s)" % (request, self._objects))
515 req = request
516 id = None
517 object = None
518 try:
519 id = req['id']
520 if id:
521 id = int(id)
522 object = self._objects[id]
523 #_log("id, object: %d %s" % (id, object))
524 except Exception, e:
525 #_log("Exception %s" % str(e))
526 pass
527 if object is None or id is None:
528 id = None
529 object = self._export
530 #_log("found object %s" % str(object))
531
532 # Handle the request via a method with a special name on the server
533 handler_name = 'handle_%s' % request.action()
534
535 try:
536 handler = getattr(self, handler_name)
537 except AttributeError:
538 raise BadRequest, request.action()
539
540 response = handler(object, request)
541
542 # figure out what to do with the response, and respond
543 # apprpriately.
544 if request.action() in ['status', 'type']:
545 # have to handle these specially since we want to
546 # pickle up the actual value and not return a proxy
547 self.respond(['value', response])
548 elif callable(response):
549 #_log("callable %s" % response)
550 self.respond(['callable'])
551 elif self.is_value(response):
552 self.respond(['value', response])
553 else:
554 self._objects[self._next_id] = response
555 #_log("objects: %s" % str(self._objects))
556 self.respond(['object', self._next_id])
557 self._next_id += 1
558 except SystemExit, e:
559 raise e
560 except Exception, e:
561 self.write_exception(e)
562 except:
563 self.write_exception(sys.exc_info()[0])
564
565 def is_value(self, value):
566 """\
567@brief Test if value should be serialized as a simple dataset.
568@param value The value to test.
569@return Returns true if value is a simple serializeable set of data.
570"""
571 return type(value) in (str,unicode,int,float,long,bool,type(None))
572
573 def respond(self, body):
574 _log("responding with: %s" % body)
575 #_log("objects: %s" % self._objects)
576 s = cPickle.dumps(body)
577 _log(`s`)
578 str = _write_lp_hunk(self._out, s)
579
580 def write_exception(self, e):
581 """@brief Helper method to respond with an exception."""
582 #_log("exception: %s" % sys.exc_info()[0])
583 # TODO: serialize traceback using generalization of code from mulib.htmlexception
584 self.respond(['exception', e])
585 global _g_debug_mode
586 if _g_debug_mode:
587 _log("traceback: %s" % traceback.format_tb(sys.exc_info()[2]))
588
589
590# test function used for testing that final except clause
591def raise_a_weird_error():
592 raise "oh noes you can raise a string"
593
594# test function used for testing return of unpicklable exceptions
595def raise_an_unpicklable_error():
596 class Unpicklable(Exception):
597 pass
598 raise Unpicklable()
599
600# test function used for testing return of picklable exceptions
601def raise_standard_error():
602 raise FloatingPointError()
603
604# test function to make sure print doesn't break the wrapper
605def print_string(str):
606 print str
607
608# test function to make sure printing on stdout doesn't break the
609# wrapper
610def err_string(str):
611 print >>sys.stderr, str
612
613def main():
614 import optparse
615 parser = optparse.OptionParser(
616 usage="usage: %prog [options]",
617 description="Simple saranwrap.Server wrapper")
618 parser.add_option(
619 '-c', '--child', default=False, action='store_true',
620 help='Wrap an object serialed via setattr.')
621 parser.add_option(
622 '-m', '--module', type='string', dest='module', default=None,
623 help='a module to load and export.')
624 parser.add_option(
625 '-l', '--logfile', type='string', dest='logfile', default=None,
626 help='file to log to.')
627 options, args = parser.parse_args()
628 global _g_logfile
629 if options.logfile:
630 _g_logfile = open(options.logfile, 'a')
631 if options.module:
632 export = api.named(options.module)
633 server = Server(sys.stdin, sys.stdout, export)
634 elif options.child:
635 server = Server(sys.stdin, sys.stdout, {})
636
637 # *HACK: some modules may emit on stderr, which breaks everything.
638 class NullSTDOut(object):
639 def write(a, b):
640 pass
641 sys.stderr = NullSTDOut()
642 sys.stdout = NullSTDOut()
643
644 # Loop until EOF
645 server.loop()
646 if _g_logfile:
647 _g_logfile.close()
648
649
650if __name__ == "__main__":
651 main()
diff --git a/linden/indra/lib/python/indra/ipc/servicebuilder.py b/linden/indra/lib/python/indra/ipc/servicebuilder.py
index 01f2c6f..04ccee7 100644
--- a/linden/indra/lib/python/indra/ipc/servicebuilder.py
+++ b/linden/indra/lib/python/indra/ipc/servicebuilder.py
@@ -5,7 +5,7 @@
5 5
6$LicenseInfo:firstyear=2007&license=mit$ 6$LicenseInfo:firstyear=2007&license=mit$
7 7
8Copyright (c) 2007-2008, Linden Research, Inc. 8Copyright (c) 2007-2009, Linden Research, Inc.
9 9
10Permission is hereby granted, free of charge, to any person obtaining a copy 10Permission is hereby granted, free of charge, to any person obtaining a copy
11of this software and associated documentation files (the "Software"), to deal 11of this software and associated documentation files (the "Software"), to deal
diff --git a/linden/indra/lib/python/indra/ipc/tokenstream.py b/linden/indra/lib/python/indra/ipc/tokenstream.py
index 75c41a7..b96f26d 100644
--- a/linden/indra/lib/python/indra/ipc/tokenstream.py
+++ b/linden/indra/lib/python/indra/ipc/tokenstream.py
@@ -4,7 +4,7 @@
4 4
5$LicenseInfo:firstyear=2007&license=mit$ 5$LicenseInfo:firstyear=2007&license=mit$
6 6
7Copyright (c) 2007-2008, Linden Research, Inc. 7Copyright (c) 2007-2009, Linden Research, Inc.
8 8
9Permission is hereby granted, free of charge, to any person obtaining a copy 9Permission is hereby granted, free of charge, to any person obtaining a copy
10of this software and associated documentation files (the "Software"), to deal 10of this software and associated documentation files (the "Software"), to deal
diff --git a/linden/indra/lib/python/indra/ipc/webdav.py b/linden/indra/lib/python/indra/ipc/webdav.py
index de00efb..98b8499 100644
--- a/linden/indra/lib/python/indra/ipc/webdav.py
+++ b/linden/indra/lib/python/indra/ipc/webdav.py
@@ -4,7 +4,7 @@
4 4
5$LicenseInfo:firstyear=2007&license=mit$ 5$LicenseInfo:firstyear=2007&license=mit$
6 6
7Copyright (c) 2007-2008, Linden Research, Inc. 7Copyright (c) 2007-2009, Linden Research, Inc.
8 8
9Permission is hereby granted, free of charge, to any person obtaining a copy 9Permission is hereby granted, free of charge, to any person obtaining a copy
10of this software and associated documentation files (the "Software"), to deal 10of this software and associated documentation files (the "Software"), to deal
diff --git a/linden/indra/lib/python/indra/ipc/xml_rpc.py b/linden/indra/lib/python/indra/ipc/xml_rpc.py
index 7473d31..47536c1 100644
--- a/linden/indra/lib/python/indra/ipc/xml_rpc.py
+++ b/linden/indra/lib/python/indra/ipc/xml_rpc.py
@@ -4,7 +4,7 @@
4 4
5$LicenseInfo:firstyear=2006&license=mit$ 5$LicenseInfo:firstyear=2006&license=mit$
6 6
7Copyright (c) 2006-2008, Linden Research, Inc. 7Copyright (c) 2006-2009, Linden Research, Inc.
8 8
9Permission is hereby granted, free of charge, to any person obtaining a copy 9Permission is hereby granted, free of charge, to any person obtaining a copy
10of this software and associated documentation files (the "Software"), to deal 10of this software and associated documentation files (the "Software"), to deal
diff --git a/linden/indra/lib/python/indra/util/__init__.py b/linden/indra/lib/python/indra/util/__init__.py
index 3134c2d..b004e58 100644
--- a/linden/indra/lib/python/indra/util/__init__.py
+++ b/linden/indra/lib/python/indra/util/__init__.py
@@ -4,7 +4,7 @@
4 4
5$LicenseInfo:firstyear=2006&license=mit$ 5$LicenseInfo:firstyear=2006&license=mit$
6 6
7Copyright (c) 2006-2008, Linden Research, Inc. 7Copyright (c) 2006-2009, Linden Research, Inc.
8 8
9Permission is hereby granted, free of charge, to any person obtaining a copy 9Permission is hereby granted, free of charge, to any person obtaining a copy
10of this software and associated documentation files (the "Software"), to deal 10of this software and associated documentation files (the "Software"), to deal
diff --git a/linden/indra/lib/python/indra/util/fastest_elementtree.py b/linden/indra/lib/python/indra/util/fastest_elementtree.py
index 2470143..3e2189c 100644
--- a/linden/indra/lib/python/indra/util/fastest_elementtree.py
+++ b/linden/indra/lib/python/indra/util/fastest_elementtree.py
@@ -4,7 +4,7 @@
4 4
5$LicenseInfo:firstyear=2008&license=mit$ 5$LicenseInfo:firstyear=2008&license=mit$
6 6
7Copyright (c) 2008, Linden Research, Inc. 7Copyright (c) 2008-2009, Linden Research, Inc.
8 8
9Permission is hereby granted, free of charge, to any person obtaining a copy 9Permission is hereby granted, free of charge, to any person obtaining a copy
10of this software and associated documentation files (the "Software"), to deal 10of this software and associated documentation files (the "Software"), to deal
diff --git a/linden/indra/lib/python/indra/util/helpformatter.py b/linden/indra/lib/python/indra/util/helpformatter.py
index 8b86b87..ba5c9b6 100644
--- a/linden/indra/lib/python/indra/util/helpformatter.py
+++ b/linden/indra/lib/python/indra/util/helpformatter.py
@@ -5,7 +5,7 @@
5 5
6$LicenseInfo:firstyear=2007&license=mit$ 6$LicenseInfo:firstyear=2007&license=mit$
7 7
8Copyright (c) 2007-2008, Linden Research, Inc. 8Copyright (c) 2007-2009, Linden Research, Inc.
9 9
10Permission is hereby granted, free of charge, to any person obtaining a copy 10Permission is hereby granted, free of charge, to any person obtaining a copy
11of this software and associated documentation files (the "Software"), to deal 11of this software and associated documentation files (the "Software"), to deal
diff --git a/linden/indra/lib/python/indra/util/iterators.py b/linden/indra/lib/python/indra/util/iterators.py
new file mode 100644
index 0000000..9013fa6
--- /dev/null
+++ b/linden/indra/lib/python/indra/util/iterators.py
@@ -0,0 +1,63 @@
1"""\
2@file iterators.py
3@brief Useful general-purpose iterators.
4
5$LicenseInfo:firstyear=2008&license=mit$
6
7Copyright (c) 2008-2009, Linden Research, Inc.
8
9Permission is hereby granted, free of charge, to any person obtaining a copy
10of this software and associated documentation files (the "Software"), to deal
11in the Software without restriction, including without limitation the rights
12to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13copies of the Software, and to permit persons to whom the Software is
14furnished to do so, subject to the following conditions:
15
16The above copyright notice and this permission notice shall be included in
17all copies or substantial portions of the Software.
18
19THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25THE SOFTWARE.
26$/LicenseInfo$
27"""
28
29from __future__ import nested_scopes
30
31def iter_chunks(rows, aggregate_size=100):
32 """
33 Given an iterable set of items (@p rows), produces lists of up to @p
34 aggregate_size items at a time, for example:
35
36 iter_chunks([1,2,3,4,5,6,7,8,9,10], 3)
37
38 Values for @p aggregate_size < 1 will raise ValueError.
39
40 Will return a generator that produces, in the following order:
41 - [1, 2, 3]
42 - [4, 5, 6]
43 - [7, 8, 9]
44 - [10]
45 """
46 if aggregate_size < 1:
47 raise ValueError()
48
49 def iter_chunks_inner():
50 row_iter = iter(rows)
51 done = False
52 agg = []
53 while not done:
54 try:
55 row = row_iter.next()
56 agg.append(row)
57 except StopIteration:
58 done = True
59 if agg and (len(agg) >= aggregate_size or done):
60 yield agg
61 agg = []
62
63 return iter_chunks_inner()
diff --git a/linden/indra/lib/python/indra/util/iterators_test.py b/linden/indra/lib/python/indra/util/iterators_test.py
new file mode 100755
index 0000000..66928c8
--- /dev/null
+++ b/linden/indra/lib/python/indra/util/iterators_test.py
@@ -0,0 +1,72 @@
1"""\
2@file iterators_test.py
3@brief Test cases for iterators module.
4
5$LicenseInfo:firstyear=2008&license=mit$
6
7Copyright (c) 2008-2009, Linden Research, Inc.
8
9Permission is hereby granted, free of charge, to any person obtaining a copy
10of this software and associated documentation files (the "Software"), to deal
11in the Software without restriction, including without limitation the rights
12to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13copies of the Software, and to permit persons to whom the Software is
14furnished to do so, subject to the following conditions:
15
16The above copyright notice and this permission notice shall be included in
17all copies or substantial portions of the Software.
18
19THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25THE SOFTWARE.
26$/LicenseInfo$
27"""
28
29import unittest
30
31from indra.util.iterators import iter_chunks
32
33class TestIterChunks(unittest.TestCase):
34 """Unittests for iter_chunks"""
35 def test_bad_agg_size(self):
36 rows = [1,2,3,4]
37 self.assertRaises(ValueError, iter_chunks, rows, 0)
38 self.assertRaises(ValueError, iter_chunks, rows, -1)
39
40 try:
41 for i in iter_chunks(rows, 0):
42 pass
43 except ValueError:
44 pass
45 else:
46 self.fail()
47
48 try:
49 result = list(iter_chunks(rows, 0))
50 except ValueError:
51 pass
52 else:
53 self.fail()
54 def test_empty(self):
55 rows = []
56 result = list(iter_chunks(rows))
57 self.assertEqual(result, [])
58 def test_small(self):
59 rows = [[1]]
60 result = list(iter_chunks(rows, 2))
61 self.assertEqual(result, [[[1]]])
62 def test_size(self):
63 rows = [[1],[2]]
64 result = list(iter_chunks(rows, 2))
65 self.assertEqual(result, [[[1],[2]]])
66 def test_multi_agg(self):
67 rows = [[1],[2],[3],[4],[5]]
68 result = list(iter_chunks(rows, 2))
69 self.assertEqual(result, [[[1],[2]],[[3],[4]],[[5]]])
70
71if __name__ == "__main__":
72 unittest.main()
diff --git a/linden/indra/lib/python/indra/util/llmanifest.py b/linden/indra/lib/python/indra/util/llmanifest.py
index a00d242..12e33f2 100644
--- a/linden/indra/lib/python/indra/util/llmanifest.py
+++ b/linden/indra/lib/python/indra/util/llmanifest.py
@@ -5,7 +5,7 @@
5 5
6$LicenseInfo:firstyear=2007&license=mit$ 6$LicenseInfo:firstyear=2007&license=mit$
7 7
8Copyright (c) 2007-2008, Linden Research, Inc. 8Copyright (c) 2007-2009, Linden Research, Inc.
9 9
10Permission is hereby granted, free of charge, to any person obtaining a copy 10Permission is hereby granted, free of charge, to any person obtaining a copy
11of this software and associated documentation files (the "Software"), to deal 11of this software and associated documentation files (the "Software"), to deal
@@ -452,7 +452,7 @@ class LLManifest(object):
452 # *TODO is this gonna be useful? 452 # *TODO is this gonna be useful?
453 print "Cleaning up " + c 453 print "Cleaning up " + c
454 454
455 def process_file(self, src, dst): 455 def process_file(self, src, dst, strip=False):
456 if self.includes(src, dst): 456 if self.includes(src, dst):
457# print src, "=>", dst 457# print src, "=>", dst
458 for action in self.actions: 458 for action in self.actions:
@@ -460,7 +460,7 @@ class LLManifest(object):
460 method = getattr(self, methodname, None) 460 method = getattr(self, methodname, None)
461 if method is not None: 461 if method is not None:
462 method(src, dst) 462 method(src, dst)
463 self.file_list.append([src, dst]) 463 self.file_list.append([src, dst, strip])
464 return 1 464 return 1
465 else: 465 else:
466 sys.stdout.write(" (excluding %r, %r)" % (src, dst)) 466 sys.stdout.write(" (excluding %r, %r)" % (src, dst))
@@ -607,7 +607,7 @@ class LLManifest(object):
607 d = src_re.sub(d_template, s.replace('\\', '/')) 607 d = src_re.sub(d_template, s.replace('\\', '/'))
608 yield os.path.normpath(s), os.path.normpath(d) 608 yield os.path.normpath(s), os.path.normpath(d)
609 609
610 def path(self, src, dst=None): 610 def path(self, src, dst=None, strip=False):
611 sys.stdout.write("Processing %s => %s ... " % (src, dst)) 611 sys.stdout.write("Processing %s => %s ... " % (src, dst))
612 sys.stdout.flush() 612 sys.stdout.flush()
613 if src == None: 613 if src == None:
@@ -622,7 +622,7 @@ class LLManifest(object):
622 if self.wildcard_pattern.search(src): 622 if self.wildcard_pattern.search(src):
623 for s,d in self.expand_globs(src, dst): 623 for s,d in self.expand_globs(src, dst):
624 assert(s != d) 624 assert(s != d)
625 count += self.process_file(s, d) 625 count += self.process_file(s, d, strip)
626 else: 626 else:
627 # if we're specifying a single path (not a glob), 627 # if we're specifying a single path (not a glob),
628 # we should error out if it doesn't exist 628 # we should error out if it doesn't exist
@@ -631,7 +631,7 @@ class LLManifest(object):
631 if os.path.isdir(src): 631 if os.path.isdir(src):
632 count += self.process_directory(src, dst) 632 count += self.process_directory(src, dst)
633 else: 633 else:
634 count += self.process_file(src, dst) 634 count += self.process_file(src, dst, strip)
635 return count 635 return count
636 try: 636 try:
637 count = try_path(os.path.join(self.get_src_prefix(), src)) 637 count = try_path(os.path.join(self.get_src_prefix(), src))
diff --git a/linden/indra/lib/python/indra/util/llperformance.py b/linden/indra/lib/python/indra/util/llperformance.py
new file mode 100755
index 0000000..7c52730
--- /dev/null
+++ b/linden/indra/lib/python/indra/util/llperformance.py
@@ -0,0 +1,158 @@
1#!/usr/bin/python
2
3# ------------------------------------------------
4# Sim metrics utility functions.
5
6import glob, os, time, sys, stat, exceptions
7
8from indra.base import llsd
9
10gBlockMap = {} #Map of performance metric data with function hierarchy information.
11gCurrentStatPath = ""
12
13gIsLoggingEnabled=False
14
15class LLPerfStat:
16 def __init__(self,key):
17 self.mTotalTime = 0
18 self.mNumRuns = 0
19 self.mName=key
20 self.mTimeStamp = int(time.time()*1000)
21 self.mUTCTime = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
22
23 def __str__(self):
24 return "%f" % self.mTotalTime
25
26 def start(self):
27 self.mStartTime = int(time.time() * 1000000)
28 self.mNumRuns += 1
29
30 def stop(self):
31 execution_time = int(time.time() * 1000000) - self.mStartTime
32 self.mTotalTime += execution_time
33
34 def get_map(self):
35 results={}
36 results['name']=self.mName
37 results['utc_time']=self.mUTCTime
38 results['timestamp']=self.mTimeStamp
39 results['us']=self.mTotalTime
40 results['count']=self.mNumRuns
41 return results
42
43class PerfError(exceptions.Exception):
44 def __init__(self):
45 return
46
47 def __Str__(self):
48 print "","Unfinished LLPerfBlock"
49
50class LLPerfBlock:
51 def __init__( self, key ):
52 global gBlockMap
53 global gCurrentStatPath
54 global gIsLoggingEnabled
55
56 #Check to see if we're running metrics right now.
57 if gIsLoggingEnabled:
58 self.mRunning = True #Mark myself as running.
59
60 self.mPreviousStatPath = gCurrentStatPath
61 gCurrentStatPath += "/" + key
62 if gCurrentStatPath not in gBlockMap:
63 gBlockMap[gCurrentStatPath] = LLPerfStat(key)
64
65 self.mStat = gBlockMap[gCurrentStatPath]
66 self.mStat.start()
67
68 def finish( self ):
69 global gBlockMap
70 global gIsLoggingEnabled
71
72 if gIsLoggingEnabled:
73 self.mStat.stop()
74 self.mRunning = False
75 gCurrentStatPath = self.mPreviousStatPath
76
77# def __del__( self ):
78# if self.mRunning:
79# #SPATTERS FIXME
80# raise PerfError
81
82class LLPerformance:
83 #--------------------------------------------------
84 # Determine whether or not we want to log statistics
85
86 def __init__( self, process_name = "python" ):
87 self.process_name = process_name
88 self.init_testing()
89 self.mTimeStamp = int(time.time()*1000)
90 self.mUTCTime = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
91
92 def init_testing( self ):
93 global gIsLoggingEnabled
94
95 host_performance_file = "/dev/shm/simperf/simperf_proc_config.llsd"
96
97 #If file exists, open
98 if os.path.exists(host_performance_file):
99 file = open (host_performance_file,'r')
100
101 #Read serialized LLSD from file.
102 body = llsd.parse(file.read())
103
104 #Calculate time since file last modified.
105 stats = os.stat(host_performance_file)
106 now = time.time()
107 mod = stats[stat.ST_MTIME]
108 age = now - mod
109
110 if age < ( body['duration'] ):
111 gIsLoggingEnabled = True
112
113
114 def get ( self ):
115 global gIsLoggingEnabled
116 return gIsLoggingEnabled
117
118 #def output(self,ptr,path):
119 # if 'stats' in ptr:
120 # stats = ptr['stats']
121 # self.mOutputPtr[path] = stats.get_map()
122
123 # if 'children' in ptr:
124 # children=ptr['children']
125
126 # curptr = self.mOutputPtr
127 # curchildren={}
128 # curptr['children'] = curchildren
129
130 # for key in children:
131 # curchildren[key]={}
132 # self.mOutputPtr = curchildren[key]
133 # self.output(children[key],path + '/' + key)
134
135 def done(self):
136 global gBlockMap
137
138 if not self.get():
139 return
140
141 output_name = "/dev/shm/simperf/%s_proc.%d.llsd" % (self.process_name, os.getpid())
142 output_file = open(output_name, 'w')
143 process_info = {
144 "name" : self.process_name,
145 "pid" : os.getpid(),
146 "ppid" : os.getppid(),
147 "timestamp" : self.mTimeStamp,
148 "utc_time" : self.mUTCTime,
149 }
150 output_file.write(llsd.format_notation(process_info))
151 output_file.write('\n')
152
153 for key in gBlockMap.keys():
154 gBlockMap[key] = gBlockMap[key].get_map()
155 output_file.write(llsd.format_notation(gBlockMap))
156 output_file.write('\n')
157 output_file.close()
158
diff --git a/linden/indra/lib/python/indra/util/llsubprocess.py b/linden/indra/lib/python/indra/util/llsubprocess.py
index 1c107d9..c4c4073 100644
--- a/linden/indra/lib/python/indra/util/llsubprocess.py
+++ b/linden/indra/lib/python/indra/util/llsubprocess.py
@@ -6,7 +6,7 @@
6 6
7$LicenseInfo:firstyear=2007&license=mit$ 7$LicenseInfo:firstyear=2007&license=mit$
8 8
9Copyright (c) 2007-2008, Linden Research, Inc. 9Copyright (c) 2007-2009, Linden Research, Inc.
10 10
11Permission is hereby granted, free of charge, to any person obtaining a copy 11Permission is hereby granted, free of charge, to any person obtaining a copy
12of this software and associated documentation files (the "Software"), to deal 12of this software and associated documentation files (the "Software"), to deal
diff --git a/linden/indra/lib/python/indra/util/llversion.py b/linden/indra/lib/python/indra/util/llversion.py
index fe9448f..0e59c17 100644
--- a/linden/indra/lib/python/indra/util/llversion.py
+++ b/linden/indra/lib/python/indra/util/llversion.py
@@ -5,7 +5,7 @@
5 5
6$LicenseInfo:firstyear=2006&license=mit$ 6$LicenseInfo:firstyear=2006&license=mit$
7 7
8Copyright (c) 2006-2008, Linden Research, Inc. 8Copyright (c) 2006-2009, Linden Research, Inc.
9 9
10Permission is hereby granted, free of charge, to any person obtaining a copy 10Permission is hereby granted, free of charge, to any person obtaining a copy
11of this software and associated documentation files (the "Software"), to deal 11of this software and associated documentation files (the "Software"), to deal
diff --git a/linden/indra/lib/python/indra/util/named_query.py b/linden/indra/lib/python/indra/util/named_query.py
index 788fb0e..822f783 100644
--- a/linden/indra/lib/python/indra/util/named_query.py
+++ b/linden/indra/lib/python/indra/util/named_query.py
@@ -6,7 +6,7 @@
6 6
7$LicenseInfo:firstyear=2007&license=mit$ 7$LicenseInfo:firstyear=2007&license=mit$
8 8
9Copyright (c) 2007-2008, Linden Research, Inc. 9Copyright (c) 2007-2009, Linden Research, Inc.
10 10
11Permission is hereby granted, free of charge, to any person obtaining a copy 11Permission is hereby granted, free of charge, to any person obtaining a copy
12of this software and associated documentation files (the "Software"), to deal 12of this software and associated documentation files (the "Software"), to deal
@@ -65,9 +65,7 @@ def _init_g_named_manager(sql_dir = None):
65 65
66 # extra fallback directory in case config doesn't return what we want 66 # extra fallback directory in case config doesn't return what we want
67 if sql_dir is None: 67 if sql_dir is None:
68 sql_dir = os.path.abspath( 68 sql_dir = os.path.join(os.path.dirname(__file__), "..", "..", "..", "..", "web", "dataservice", "sql")
69 os.path.join(
70 os.path.realpath(os.path.dirname(__file__)), "..", "..", "..", "..", "web", "dataservice", "sql"))
71 69
72 global _g_named_manager 70 global _g_named_manager
73 _g_named_manager = NamedQueryManager( 71 _g_named_manager = NamedQueryManager(
diff --git a/linden/indra/lib/python/indra/util/shutil2.py b/linden/indra/lib/python/indra/util/shutil2.py
index 2c504c2..9e2e7a6 100644
--- a/linden/indra/lib/python/indra/util/shutil2.py
+++ b/linden/indra/lib/python/indra/util/shutil2.py
@@ -4,7 +4,7 @@
4 4
5$LicenseInfo:firstyear=2007&license=mit$ 5$LicenseInfo:firstyear=2007&license=mit$
6 6
7Copyright (c) 2007-2008, Linden Research, Inc. 7Copyright (c) 2007-2009, Linden Research, Inc.
8 8
9Permission is hereby granted, free of charge, to any person obtaining a copy 9Permission is hereby granted, free of charge, to any person obtaining a copy
10of this software and associated documentation files (the "Software"), to deal 10of this software and associated documentation files (the "Software"), to deal
diff --git a/linden/indra/lib/python/indra/util/simperf_host_xml_parser.py b/linden/indra/lib/python/indra/util/simperf_host_xml_parser.py
new file mode 100755
index 0000000..672c105
--- /dev/null
+++ b/linden/indra/lib/python/indra/util/simperf_host_xml_parser.py
@@ -0,0 +1,338 @@
1#!/usr/bin/env python
2"""\
3@file simperf_host_xml_parser.py
4@brief Digest collector's XML dump and convert to simple dict/list structure
5
6$LicenseInfo:firstyear=2008&license=mit$
7
8Copyright (c) 2008-2009, Linden Research, Inc.
9
10Permission is hereby granted, free of charge, to any person obtaining a copy
11of this software and associated documentation files (the "Software"), to deal
12in the Software without restriction, including without limitation the rights
13to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14copies of the Software, and to permit persons to whom the Software is
15furnished to do so, subject to the following conditions:
16
17The above copyright notice and this permission notice shall be included in
18all copies or substantial portions of the Software.
19
20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26THE SOFTWARE.
27$/LicenseInfo$
28"""
29
30import sys, os, getopt, time
31import simplejson
32from xml import sax
33
34
35def usage():
36 print "Usage:"
37 print sys.argv[0] + " [options]"
38 print " Convert RRD's XML dump to JSON. Script to convert the simperf_host_collector-"
39 print " generated RRD dump into JSON. Steps include converting selected named"
40 print " fields from GAUGE type to COUNTER type by computing delta with preceding"
41 print " values. Top-level named fields are:"
42 print
43 print " lastupdate Time (javascript timestamp) of last data sample"
44 print " step Time in seconds between samples"
45 print " ds Data specification (name/type) for each column"
46 print " database Table of data samples, one time step per row"
47 print
48 print "Options:"
49 print " -i, --in Input settings filename. (Default: stdin)"
50 print " -o, --out Output settings filename. (Default: stdout)"
51 print " -h, --help Print this message and exit."
52 print
53 print "Example: %s -i rrddump.xml -o rrddump.json" % sys.argv[0]
54 print
55 print "Interfaces:"
56 print " class SimPerfHostXMLParser() # SAX content handler"
57 print " def simperf_host_xml_fixup(parser) # post-parse value fixup"
58
59class SimPerfHostXMLParser(sax.handler.ContentHandler):
60
61 def __init__(self):
62 pass
63
64 def startDocument(self):
65 self.rrd_last_update = 0 # public
66 self.rrd_step = 0 # public
67 self.rrd_ds = [] # public
68 self.rrd_records = [] # public
69 self._rrd_level = 0
70 self._rrd_parse_state = 0
71 self._rrd_chars = ""
72 self._rrd_capture = False
73 self._rrd_ds_val = {}
74 self._rrd_data_row = []
75 self._rrd_data_row_has_nan = False
76
77 def endDocument(self):
78 pass
79
80 # Nasty little ad-hoc state machine to extract the elements that are
81 # necessary from the 'rrdtool dump' XML output. The same element
82 # name '<ds>' is used for two different data sets so we need to pay
83 # some attention to the actual structure to get the ones we want
84 # and ignore the ones we don't.
85
86 def startElement(self, name, attrs):
87 self._rrd_level = self._rrd_level + 1
88 self._rrd_capture = False
89 if self._rrd_level == 1:
90 if name == "rrd" and self._rrd_parse_state == 0:
91 self._rrd_parse_state = 1 # In <rrd>
92 self._rrd_capture = True
93 self._rrd_chars = ""
94 elif self._rrd_level == 2:
95 if self._rrd_parse_state == 1:
96 if name == "lastupdate":
97 self._rrd_parse_state = 2 # In <rrd><lastupdate>
98 self._rrd_capture = True
99 self._rrd_chars = ""
100 elif name == "step":
101 self._rrd_parse_state = 3 # In <rrd><step>
102 self._rrd_capture = True
103 self._rrd_chars = ""
104 elif name == "ds":
105 self._rrd_parse_state = 4 # In <rrd><ds>
106 self._rrd_ds_val = {}
107 self._rrd_chars = ""
108 elif name == "rra":
109 self._rrd_parse_state = 5 # In <rrd><rra>
110 elif self._rrd_level == 3:
111 if self._rrd_parse_state == 4:
112 if name == "name":
113 self._rrd_parse_state = 6 # In <rrd><ds><name>
114 self._rrd_capture = True
115 self._rrd_chars = ""
116 elif name == "type":
117 self._rrd_parse_state = 7 # In <rrd><ds><type>
118 self._rrd_capture = True
119 self._rrd_chars = ""
120 elif self._rrd_parse_state == 5:
121 if name == "database":
122 self._rrd_parse_state = 8 # In <rrd><rra><database>
123 elif self._rrd_level == 4:
124 if self._rrd_parse_state == 8:
125 if name == "row":
126 self._rrd_parse_state = 9 # In <rrd><rra><database><row>
127 self._rrd_data_row = []
128 self._rrd_data_row_has_nan = False
129 elif self._rrd_level == 5:
130 if self._rrd_parse_state == 9:
131 if name == "v":
132 self._rrd_parse_state = 10 # In <rrd><rra><database><row><v>
133 self._rrd_capture = True
134 self._rrd_chars = ""
135
136 def endElement(self, name):
137 self._rrd_capture = False
138 if self._rrd_parse_state == 10:
139 self._rrd_capture = self._rrd_level == 6
140 if self._rrd_level == 5:
141 if self._rrd_chars == "NaN":
142 self._rrd_data_row_has_nan = True
143 else:
144 self._rrd_data_row.append(self._rrd_chars)
145 self._rrd_parse_state = 9 # In <rrd><rra><database><row>
146 elif self._rrd_parse_state == 9:
147 if self._rrd_level == 4:
148 if not self._rrd_data_row_has_nan:
149 self.rrd_records.append(self._rrd_data_row)
150 self._rrd_parse_state = 8 # In <rrd><rra><database>
151 elif self._rrd_parse_state == 8:
152 if self._rrd_level == 3:
153 self._rrd_parse_state = 5 # In <rrd><rra>
154 elif self._rrd_parse_state == 7:
155 if self._rrd_level == 3:
156 self._rrd_ds_val["type"] = self._rrd_chars
157 self._rrd_parse_state = 4 # In <rrd><ds>
158 elif self._rrd_parse_state == 6:
159 if self._rrd_level == 3:
160 self._rrd_ds_val["name"] = self._rrd_chars
161 self._rrd_parse_state = 4 # In <rrd><ds>
162 elif self._rrd_parse_state == 5:
163 if self._rrd_level == 2:
164 self._rrd_parse_state = 1 # In <rrd>
165 elif self._rrd_parse_state == 4:
166 if self._rrd_level == 2:
167 self.rrd_ds.append(self._rrd_ds_val)
168 self._rrd_parse_state = 1 # In <rrd>
169 elif self._rrd_parse_state == 3:
170 if self._rrd_level == 2:
171 self.rrd_step = long(self._rrd_chars)
172 self._rrd_parse_state = 1 # In <rrd>
173 elif self._rrd_parse_state == 2:
174 if self._rrd_level == 2:
175 self.rrd_last_update = long(self._rrd_chars)
176 self._rrd_parse_state = 1 # In <rrd>
177 elif self._rrd_parse_state == 1:
178 if self._rrd_level == 1:
179 self._rrd_parse_state = 0 # At top
180
181 if self._rrd_level:
182 self._rrd_level = self._rrd_level - 1
183
184 def characters(self, content):
185 if self._rrd_capture:
186 self._rrd_chars = self._rrd_chars + content.strip()
187
188def _make_numeric(value):
189 try:
190 value = float(value)
191 except:
192 value = ""
193 return value
194
195def simperf_host_xml_fixup(parser, filter_start_time = None, filter_end_time = None):
196 # Fixup for GAUGE fields that are really COUNTS. They
197 # were forced to GAUGE to try to disable rrdtool's
198 # data interpolation/extrapolation for non-uniform time
199 # samples.
200 fixup_tags = [ "cpu_user",
201 "cpu_nice",
202 "cpu_sys",
203 "cpu_idle",
204 "cpu_waitio",
205 "cpu_intr",
206 # "file_active",
207 # "file_free",
208 # "inode_active",
209 # "inode_free",
210 "netif_in_kb",
211 "netif_in_pkts",
212 "netif_in_errs",
213 "netif_in_drop",
214 "netif_out_kb",
215 "netif_out_pkts",
216 "netif_out_errs",
217 "netif_out_drop",
218 "vm_page_in",
219 "vm_page_out",
220 "vm_swap_in",
221 "vm_swap_out",
222 #"vm_mem_total",
223 #"vm_mem_used",
224 #"vm_mem_active",
225 #"vm_mem_inactive",
226 #"vm_mem_free",
227 #"vm_mem_buffer",
228 #"vm_swap_cache",
229 #"vm_swap_total",
230 #"vm_swap_used",
231 #"vm_swap_free",
232 "cpu_interrupts",
233 "cpu_switches",
234 "cpu_forks" ]
235
236 col_count = len(parser.rrd_ds)
237 row_count = len(parser.rrd_records)
238
239 # Process the last row separately, just to make all values numeric.
240 for j in range(col_count):
241 parser.rrd_records[row_count - 1][j] = _make_numeric(parser.rrd_records[row_count - 1][j])
242
243 # Process all other row/columns.
244 last_different_row = row_count - 1
245 current_row = row_count - 2
246 while current_row >= 0:
247 # Check for a different value than the previous row. If everything is the same
248 # then this is probably just a filler/bogus entry.
249 is_different = False
250 for j in range(col_count):
251 parser.rrd_records[current_row][j] = _make_numeric(parser.rrd_records[current_row][j])
252 if parser.rrd_records[current_row][j] != parser.rrd_records[last_different_row][j]:
253 # We're good. This is a different row.
254 is_different = True
255
256 if not is_different:
257 # This is a filler/bogus entry. Just ignore it.
258 for j in range(col_count):
259 parser.rrd_records[current_row][j] = float('nan')
260 else:
261 # Some tags need to be converted into deltas.
262 for j in range(col_count):
263 if parser.rrd_ds[j]["name"] in fixup_tags:
264 parser.rrd_records[last_different_row][j] = \
265 parser.rrd_records[last_different_row][j] - parser.rrd_records[current_row][j]
266 last_different_row = current_row
267
268 current_row -= 1
269
270 # Set fixup_tags in the first row to 'nan' since they aren't useful anymore.
271 for j in range(col_count):
272 if parser.rrd_ds[j]["name"] in fixup_tags:
273 parser.rrd_records[0][j] = float('nan')
274
275 # Add a timestamp to each row and to the catalog. Format and name
276 # chosen to match other simulator logging (hopefully).
277 start_time = parser.rrd_last_update - (parser.rrd_step * (row_count - 1))
278 # Build a filtered list of rrd_records if we are limited to a time range.
279 filter_records = False
280 if filter_start_time is not None or filter_end_time is not None:
281 filter_records = True
282 filtered_rrd_records = []
283 if filter_start_time is None:
284 filter_start_time = start_time * 1000
285 if filter_end_time is None:
286 filter_end_time = parser.rrd_last_update * 1000
287
288 for i in range(row_count):
289 record_timestamp = (start_time + (i * parser.rrd_step)) * 1000
290 parser.rrd_records[i].insert(0, record_timestamp)
291 if filter_records:
292 if filter_start_time <= record_timestamp and record_timestamp <= filter_end_time:
293 filtered_rrd_records.append(parser.rrd_records[i])
294
295 if filter_records:
296 parser.rrd_records = filtered_rrd_records
297
298 parser.rrd_ds.insert(0, {"type": "GAUGE", "name": "javascript_timestamp"})
299
300
301def main(argv=None):
302 opts, args = getopt.getopt(sys.argv[1:], "i:o:h", ["in=", "out=", "help"])
303 input_file = sys.stdin
304 output_file = sys.stdout
305 for o, a in opts:
306 if o in ("-i", "--in"):
307 input_file = open(a, 'r')
308 if o in ("-o", "--out"):
309 output_file = open(a, 'w')
310 if o in ("-h", "--help"):
311 usage()
312 sys.exit(0)
313
314 # Using the SAX parser as it is at least 4X faster and far, far
315 # smaller on this dataset than the DOM-based interface in xml.dom.minidom.
316 # With SAX and a 5.4MB xml file, this requires about seven seconds of
317 # wall-clock time and 32MB VSZ. With the DOM interface, about 22 seconds
318 # and over 270MB VSZ.
319
320 handler = SimPerfHostXMLParser()
321 sax.parse(input_file, handler)
322 if input_file != sys.stdin:
323 input_file.close()
324
325 # Various format fixups: string-to-num, gauge-to-counts, add
326 # a time stamp, etc.
327 simperf_host_xml_fixup(handler)
328
329 # Create JSONable dict with interesting data and format/print it
330 print >>output_file, simplejson.dumps({ "step" : handler.rrd_step,
331 "lastupdate": handler.rrd_last_update * 1000,
332 "ds" : handler.rrd_ds,
333 "database" : handler.rrd_records })
334
335 return 0
336
337if __name__ == "__main__":
338 sys.exit(main())
diff --git a/linden/indra/lib/python/indra/util/simperf_oprof_interface.py b/linden/indra/lib/python/indra/util/simperf_oprof_interface.py
new file mode 100755
index 0000000..c8d0f74
--- /dev/null
+++ b/linden/indra/lib/python/indra/util/simperf_oprof_interface.py
@@ -0,0 +1,160 @@
1#!/usr/bin/env python
2"""\
3@file simperf_oprof_interface.py
4@brief Manage OProfile data collection on a host
5
6$LicenseInfo:firstyear=2008&license=internal$
7
8Copyright (c) 2008-2009, Linden Research, Inc.
9
10The following source code is PROPRIETARY AND CONFIDENTIAL. Use of
11this source code is governed by the Linden Lab Source Code Disclosure
12Agreement ("Agreement") previously entered between you and Linden
13Lab. By accessing, using, copying, modifying or distributing this
14software, you acknowledge that you have been informed of your
15obligations under the Agreement and agree to abide by those obligations.
16
17ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
18WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
19COMPLETENESS OR PERFORMANCE.
20$/LicenseInfo$
21"""
22
23import sys, os, getopt
24import simplejson
25
26
27def usage():
28 print "Usage:"
29 print sys.argv[0] + " [options]"
30 print " Digest the OProfile report forms that come out of the"
31 print " simperf_oprof_ctl program's -r/--report command. The result"
32 print " is an array of dictionaires with the following keys:"
33 print
34 print " symbol Name of sampled, calling, or called procedure"
35 print " file Executable or library where symbol resides"
36 print " percentage Percentage contribution to profile, calls or called"
37 print " samples Sample count"
38 print " calls Methods called by the method in question (full only)"
39 print " called_by Methods calling the method (full only)"
40 print
41 print " For 'full' reports the two keys 'calls' and 'called_by' are"
42 print " themselves arrays of dictionaries based on the first four keys."
43 print
44 print "Return Codes:"
45 print " None. Aggressively digests everything. Will likely mung results"
46 print " if a program or library has whitespace in its name."
47 print
48 print "Options:"
49 print " -i, --in Input settings filename. (Default: stdin)"
50 print " -o, --out Output settings filename. (Default: stdout)"
51 print " -h, --help Print this message and exit."
52 print
53 print "Interfaces:"
54 print " class SimPerfOProfileInterface()"
55
56class SimPerfOProfileInterface:
57 def __init__(self):
58 self.isBrief = True # public
59 self.isValid = False # public
60 self.result = [] # public
61
62 def parse(self, input):
63 in_samples = False
64 for line in input:
65 if in_samples:
66 if line[0:6] == "------":
67 self.isBrief = False
68 self._parseFull(input)
69 else:
70 self._parseBrief(input, line)
71 self.isValid = True
72 return
73 try:
74 hd1, remain = line.split(None, 1)
75 if hd1 == "samples":
76 in_samples = True
77 except ValueError:
78 pass
79
80 def _parseBrief(self, input, line1):
81 try:
82 fld1, fld2, fld3, fld4 = line1.split(None, 3)
83 self.result.append({"samples" : fld1,
84 "percentage" : fld2,
85 "file" : fld3,
86 "symbol" : fld4.strip("\n")})
87 except ValueError:
88 pass
89 for line in input:
90 try:
91 fld1, fld2, fld3, fld4 = line.split(None, 3)
92 self.result.append({"samples" : fld1,
93 "percentage" : fld2,
94 "file" : fld3,
95 "symbol" : fld4.strip("\n")})
96 except ValueError:
97 pass
98
99 def _parseFull(self, input):
100 state = 0 # In 'called_by' section
101 calls = []
102 called_by = []
103 current = {}
104 for line in input:
105 if line[0:6] == "------":
106 if len(current):
107 current["calls"] = calls
108 current["called_by"] = called_by
109 self.result.append(current)
110 state = 0
111 calls = []
112 called_by = []
113 current = {}
114 else:
115 try:
116 fld1, fld2, fld3, fld4 = line.split(None, 3)
117 tmp = {"samples" : fld1,
118 "percentage" : fld2,
119 "file" : fld3,
120 "symbol" : fld4.strip("\n")}
121 except ValueError:
122 continue
123 if line[0] != " ":
124 current = tmp
125 state = 1 # In 'calls' section
126 elif state == 0:
127 called_by.append(tmp)
128 else:
129 calls.append(tmp)
130 if len(current):
131 current["calls"] = calls
132 current["called_by"] = called_by
133 self.result.append(current)
134
135
136def main(argv=None):
137 opts, args = getopt.getopt(sys.argv[1:], "i:o:h", ["in=", "out=", "help"])
138 input_file = sys.stdin
139 output_file = sys.stdout
140 for o, a in opts:
141 if o in ("-i", "--in"):
142 input_file = open(a, 'r')
143 if o in ("-o", "--out"):
144 output_file = open(a, 'w')
145 if o in ("-h", "--help"):
146 usage()
147 sys.exit(0)
148
149 oprof = SimPerfOProfileInterface()
150 oprof.parse(input_file)
151 if input_file != sys.stdin:
152 input_file.close()
153
154 # Create JSONable dict with interesting data and format/print it
155 print >>output_file, simplejson.dumps(oprof.result)
156
157 return 0
158
159if __name__ == "__main__":
160 sys.exit(main())
diff --git a/linden/indra/lib/python/indra/util/simperf_proc_interface.py b/linden/indra/lib/python/indra/util/simperf_proc_interface.py
new file mode 100755
index 0000000..62a63fa
--- /dev/null
+++ b/linden/indra/lib/python/indra/util/simperf_proc_interface.py
@@ -0,0 +1,164 @@
1#!/usr/bin/python
2
3# ----------------------------------------------------
4# Utility to extract log messages from *.<pid>.llsd
5# files that contain performance statistics.
6
7# ----------------------------------------------------
8import sys, os
9
10if os.path.exists("setup-path.py"):
11 execfile("setup-path.py")
12
13from indra.base import llsd
14
15DEFAULT_PATH="/dev/shm/simperf/"
16
17
18# ----------------------------------------------------
19# Pull out the stats and return a single document
20def parse_logfile(filename, target_column=None, verbose=False):
21 full_doc = []
22 # Open source temp log file. Let exceptions percolate up.
23 sourcefile = open( filename,'r')
24
25 if verbose:
26 print "Reading " + filename
27
28 # Parse and output all lines from the temp file
29 for line in sourcefile.xreadlines():
30 partial_doc = llsd.parse(line)
31 if partial_doc is not None:
32 if target_column is None:
33 full_doc.append(partial_doc)
34 else:
35 trim_doc = { target_column: partial_doc[target_column] }
36 if target_column != "fps":
37 trim_doc[ 'fps' ] = partial_doc[ 'fps' ]
38 trim_doc[ '/total_time' ] = partial_doc[ '/total_time' ]
39 trim_doc[ 'utc_time' ] = partial_doc[ 'utc_time' ]
40 full_doc.append(trim_doc)
41
42 sourcefile.close()
43 return full_doc
44
45# Extract just the meta info line, and the timestamp of the first/last frame entry.
46def parse_logfile_info(filename, verbose=False):
47 # Open source temp log file. Let exceptions percolate up.
48 sourcefile = open(filename, 'rU') # U is to open with Universal newline support
49
50 if verbose:
51 print "Reading " + filename
52
53 # The first line is the meta info line.
54 info_line = sourcefile.readline()
55 if not info_line:
56 sourcefile.close()
57 return None
58
59 # The rest of the lines are frames. Read the first and last to get the time range.
60 info = llsd.parse( info_line )
61 info['start_time'] = None
62 info['end_time'] = None
63 first_frame = sourcefile.readline()
64 if first_frame:
65 try:
66 info['start_time'] = int(llsd.parse(first_frame)['timestamp'])
67 except:
68 pass
69
70 # Read the file backwards to find the last two lines.
71 sourcefile.seek(0, 2)
72 file_size = sourcefile.tell()
73 offset = 1024
74 num_attempts = 0
75 end_time = None
76 if file_size < offset:
77 offset = file_size
78 while 1:
79 sourcefile.seek(-1*offset, 2)
80 read_str = sourcefile.read(offset)
81 # Remove newline at the end
82 if read_str[offset - 1] == '\n':
83 read_str = read_str[0:-1]
84 lines = read_str.split('\n')
85 full_line = None
86 if len(lines) > 2: # Got two line
87 try:
88 end_time = llsd.parse(lines[-1])['timestamp']
89 except:
90 # We couldn't parse this line. Try once more.
91 try:
92 end_time = llsd.parse(lines[-2])['timestamp']
93 except:
94 # Nope. Just move on.
95 pass
96 break
97 if len(read_str) == file_size: # Reached the beginning
98 break
99 offset += 1024
100
101 info['end_time'] = int(end_time)
102
103 sourcefile.close()
104 return info
105
106
107def parse_proc_filename(filename):
108 try:
109 name_as_list = filename.split(".")
110 cur_stat_type = name_as_list[0].split("_")[0]
111 cur_pid = name_as_list[1]
112 except IndexError, ValueError:
113 return (None, None)
114 return (cur_pid, cur_stat_type)
115
116# ----------------------------------------------------
117def get_simstats_list(path=None):
118 """ Return stats (pid, type) listed in <type>_proc.<pid>.llsd """
119 if path is None:
120 path = DEFAULT_PATH
121 simstats_list = []
122 for file_name in os.listdir(path):
123 if file_name.endswith(".llsd") and file_name != "simperf_proc_config.llsd":
124 simstats_info = parse_logfile_info(path + file_name)
125 if simstats_info is not None:
126 simstats_list.append(simstats_info)
127 return simstats_list
128
129def get_log_info_list(pid=None, stat_type=None, path=None, target_column=None, verbose=False):
130 """ Return data from all llsd files matching the pid and stat type """
131 if path is None:
132 path = DEFAULT_PATH
133 log_info_list = {}
134 for file_name in os.listdir ( path ):
135 if file_name.endswith(".llsd") and file_name != "simperf_proc_config.llsd":
136 (cur_pid, cur_stat_type) = parse_proc_filename(file_name)
137 if cur_pid is None:
138 continue
139 if pid is not None and pid != cur_pid:
140 continue
141 if stat_type is not None and stat_type != cur_stat_type:
142 continue
143 log_info_list[cur_pid] = parse_logfile(path + file_name, target_column, verbose)
144 return log_info_list
145
146def delete_simstats_files(pid=None, stat_type=None, path=None):
147 """ Delete *.<pid>.llsd files """
148 if path is None:
149 path = DEFAULT_PATH
150 del_list = []
151 for file_name in os.listdir(path):
152 if file_name.endswith(".llsd") and file_name != "simperf_proc_config.llsd":
153 (cur_pid, cur_stat_type) = parse_proc_filename(file_name)
154 if cur_pid is None:
155 continue
156 if pid is not None and pid != cur_pid:
157 continue
158 if stat_type is not None and stat_type != cur_stat_type:
159 continue
160 del_list.append(cur_pid)
161 # Allow delete related exceptions to percolate up if this fails.
162 os.unlink(os.path.join(DEFAULT_PATH, file_name))
163 return del_list
164
diff --git a/linden/indra/lib/python/indra/util/term.py b/linden/indra/lib/python/indra/util/term.py
index 8238b78..8c316a1 100644
--- a/linden/indra/lib/python/indra/util/term.py
+++ b/linden/indra/lib/python/indra/util/term.py
@@ -4,7 +4,7 @@
4 4
5$LicenseInfo:firstyear=2007&license=mit$ 5$LicenseInfo:firstyear=2007&license=mit$
6 6
7Copyright (c) 2007-2008, Linden Research, Inc. 7Copyright (c) 2007-2009, Linden Research, Inc.
8 8
9Permission is hereby granted, free of charge, to any person obtaining a copy 9Permission is hereby granted, free of charge, to any person obtaining a copy
10of this software and associated documentation files (the "Software"), to deal 10of this software and associated documentation files (the "Software"), to deal