Search Results

Search found 1837 results on 74 pages for 'act'.

Page 74/74 | < Previous Page | 70 71 72 73 74 

  • What&rsquo;s New in ASP.NET 4.0 Part Two: WebForms and Visual Studio Enhancements

    - by Rick Strahl
    In the last installment I talked about the core changes in the ASP.NET runtime that I’ve been taking advantage of. In this column, I’ll cover the changes to the Web Forms engine and some of the cool improvements in Visual Studio that make Web and general development easier. WebForms The WebForms engine is the area that has received most significant changes in ASP.NET 4.0. Probably the most widely anticipated features are related to managing page client ids and of ViewState on WebForm pages. Take Control of Your ClientIDs Unique ClientID generation in ASP.NET has been one of the most complained about “features” in ASP.NET. Although there’s a very good technical reason for these unique generated ids - they guarantee unique ids for each and every server control on a page - these unique and generated ids often get in the way of client-side JavaScript development and CSS styling as it’s often inconvenient and fragile to work with the long, generated ClientIDs. In ASP.NET 4.0 you can now specify an explicit client id mode on each control or each naming container parent control to control how client ids are generated. By default, ASP.NET generates mangled client ids for any control contained in a naming container (like a Master Page, or a User Control for example). The key to ClientID management in ASP.NET 4.0 are the new ClientIDMode and ClientIDRowSuffix properties. ClientIDMode supports four different ClientID generation settings shown below. For the following examples, imagine that you have a Textbox control named txtName inside of a master page control container on a WebForms page. <%@Page Language="C#"      MasterPageFile="~/Site.Master"     CodeBehind="WebForm2.aspx.cs"     Inherits="WebApplication1.WebForm2"  %> <asp:Content ID="content"  ContentPlaceHolderID="content"               runat="server"               ClientIDMode="Static" >       <asp:TextBox runat="server" ID="txtName" /> </asp:Content> The four available ClientIDMode values are: AutoID This is the existing behavior in ASP.NET 1.x-3.x where full naming container munging takes place. <input name="ctl00$content$txtName" type="text"        id="ctl00_content_txtName" /> This should be familiar to any ASP.NET developer and results in fairly unpredictable client ids that can easily change if the containership hierarchy changes. For example, removing the master page changes the name in this case, so if you were to move a block of script code that works against the control to a non-Master page, the script code immediately breaks. Static This option is the most deterministic setting that forces the control’s ClientID to use its ID value directly. No naming container naming at all is applied and you end up with clean client ids: <input name="ctl00$content$txtName"         type="text" id="txtName" /> Note that the name property which is used for postback variables to the server still is munged, but the ClientID property is displayed simply as the ID value that you have assigned to the control. This option is what most of us want to use, but you have to be clear on that because it can potentially cause conflicts with other controls on the page. If there are several instances of the same naming container (several instances of the same user control for example) there can easily be a client id naming conflict. Note that if you assign Static to a data-bound control, like a list child control in templates, you do not get unique ids either, so for list controls where you rely on unique id for child controls, you’ll probably want to use Predictable rather than Static. I’ll write more on this a little later when I discuss ClientIDRowSuffix. Predictable The previous two values are pretty self-explanatory. Predictable however, requires some explanation. To me at least it’s not in the least bit predictable. MSDN defines this value as follows: This algorithm is used for controls that are in data-bound controls. The ClientID value is generated by concatenating the ClientID value of the parent naming container with the ID value of the control. If the control is a data-bound control that generates multiple rows, the value of the data field specified in the ClientIDRowSuffix property is added at the end. For the GridView control, multiple data fields can be specified. If the ClientIDRowSuffix property is blank, a sequential number is added at the end instead of a data-field value. Each segment is separated by an underscore character (_). The key that makes this value a bit confusing is that it relies on the parent NamingContainer’s ClientID to build its own ClientID value. This effectively means that the value is not predictable at all but rather very tightly coupled to the parent naming container’s ClientIDMode setting. For my simple textbox example, if the ClientIDMode property of the parent naming container (Page in this case) is set to “Predictable” you’ll get this: <input name="ctl00$content$txtName" type="text"         id="content_txtName" /> which gives an id that based on walking up to the currently active naming container (the MasterPage content container) and starting the id formatting from there downward. Think of this as a semi unique name that’s guaranteed unique only for the naming container. If, on the other hand, the Page is set to “AutoID” you get the following with Predictable on txtName: <input name="ctl00$content$txtName" type="text"         id="ctl00_content_txtName" /> The latter is effectively the same as if you specified AutoID because it inherits the AutoID naming from the Page and Content Master Page control of the page. But again - predictable behavior always depends on the parent naming container and how it generates its id, so the id may not always be exactly the same as the AutoID generated value because somewhere in the NamingContainer chain the ClientIDMode setting may be set to a different value. For example, if you had another naming container in the middle that was set to Static you’d end up effectively with an id that starts with the NamingContainers id rather than the whole ctl000_content munging. The most common use for Predictable is likely to be for data-bound controls, which results in each data bound item getting a unique ClientID. Unfortunately, even here the behavior can be very unpredictable depending on which data-bound control you use - I found significant differences in how template controls in a GridView behave from those that are used in a ListView control. For example, GridView creates clean child ClientIDs, while ListView still has a naming container in the ClientID, presumably because of the template container on which you can’t set ClientIDMode. Predictable is useful, but only if all naming containers down the chain use this setting. Otherwise you’re right back to the munged ids that are pretty unpredictable. Another property, ClientIDRowSuffix, can be used in combination with ClientIDMode of Predictable to force a suffix onto list client controls. For example: <asp:GridView runat="server" ID="gvItems"              AutoGenerateColumns="false"             ClientIDMode="Static"              ClientIDRowSuffix="Id">     <Columns>     <asp:TemplateField>         <ItemTemplate>             <asp:Label runat="server" id="txtName"                        Text='<%# Eval("Name") %>'                   ClientIDMode="Predictable"/>         </ItemTemplate>     </asp:TemplateField>     <asp:TemplateField>         <ItemTemplate>         <asp:Label runat="server" id="txtId"                     Text='<%# Eval("Id") %>'                     ClientIDMode="Predictable" />         </ItemTemplate>     </asp:TemplateField>     </Columns>  </asp:GridView> generates client Ids inside of a column in the master page described earlier: <td>     <span id="txtName_0">Rick</span> </td> where the value after the underscore is the ClientIDRowSuffix field - in this case “Id” of the item data bound to the control. Note that all of the child controls require ClientIDMode=”Predictable” in order for the ClientIDRowSuffix to be applied, and the parent GridView controls need to be set to Static either explicitly or via Naming Container inheritance to give these simple names. It’s a bummer that ClientIDRowSuffix doesn’t work with Static to produce this automatically. Another real problem is that other controls process the ClientIDMode differently. For example, a ListView control processes the Predictable ClientIDMode differently and produces the following with the Static ListView and Predictable child controls: <span id="ctrl0_txtName_0">Rick</span> I couldn’t even figure out a way using ClientIDMode to get a simple ID that also uses a suffix short of falling back to manually generated ids using <%= %> expressions instead. Given the inconsistencies inside of list controls using <%= %>, ids for the ListView might not be a bad idea anyway. Inherit The final setting is Inherit, which is the default for all controls except Page. This means that controls by default inherit the parent naming container’s ClientIDMode setting. For more detailed information on ClientID behavior and different scenarios you can check out a blog post of mine on this subject: http://www.west-wind.com/weblog/posts/54760.aspx. ClientID Enhancements Summary The ClientIDMode property is a welcome addition to ASP.NET 4.0. To me this is probably the most useful WebForms feature as it allows me to generate clean IDs simply by setting ClientIDMode="Static" on either the page or inside of Web.config (in the Pages section) which applies the setting down to the entire page which is my 95% scenario. For the few cases when it matters - for list controls and inside of multi-use user controls or custom server controls) - I can use Predictable or even AutoID to force controls to unique names. For application-level page development, this is easy to accomplish and provides maximum usability for working with client script code against page controls. ViewStateMode Another area of large criticism for WebForms is ViewState. ViewState is used internally by ASP.NET to persist page-level changes to non-postback properties on controls as pages post back to the server. It’s a useful mechanism that works great for the overall mechanics of WebForms, but it can also cause all sorts of overhead for page operation as ViewState can very quickly get out of control and consume huge amounts of bandwidth in your page content. ViewState can also wreak havoc with client-side scripting applications that modify control properties that are tracked by ViewState, which can produce very unpredictable results on a Postback after client-side updates. Over the years in my own development, I’ve often turned off ViewState on pages to reduce overhead. Yes, you lose some functionality, but you can easily implement most of the common functionality in non-ViewState workarounds. Relying less on heavy ViewState controls and sticking with simpler controls or raw HTML constructs avoids getting around ViewState problems. In ASP.NET 3.x and prior, it wasn’t easy to control ViewState - you could turn it on or off and if you turned it off at the page or web.config level, you couldn’t turn it back on for specific controls. In short, it was an all or nothing approach. With ASP.NET 4.0, the new ViewStateMode property gives you more control. It allows you to disable ViewState globally either on the page or web.config level and then turn it back on for specific controls that might need it. ViewStateMode only works when EnableViewState="true" on the page or web.config level (which is the default). You can then use ViewStateMode of Disabled, Enabled or Inherit to control the ViewState settings on the page. If you’re shooting for minimal ViewState usage, the ideal situation is to set ViewStateMode to disabled on the Page or web.config level and only turn it back on particular controls: <%@Page Language="C#"      CodeBehind="WebForm2.aspx.cs"     Inherits="Westwind.WebStore.WebForm2"        ClientIDMode="Static"                ViewStateMode="Disabled"     EnableViewState="true"  %> <!-- this control has viewstate  --> <asp:TextBox runat="server" ID="txtName"  ViewStateMode="Enabled" />       <!-- this control has no viewstate - it inherits  from parent container --> <asp:TextBox runat="server" ID="txtAddress" /> Note that the EnableViewState="true" at the Page level isn’t required since it’s the default, but it’s important that the value is true. ViewStateMode has no effect if EnableViewState="false" at the page level. The main benefit of ViewStateMode is that it allows you to more easily turn off ViewState for most of the page and enable only a few key controls that might need it. For me personally, this is a perfect combination as most of my WebForm apps can get away without any ViewState at all. But some controls - especially third party controls - often don’t work well without ViewState enabled, and now it’s much easier to selectively enable controls rather than the old way, which required you to pretty much turn off ViewState for all controls that you didn’t want ViewState on. Inline HTML Encoding HTML encoding is an important feature to prevent cross-site scripting attacks in data entered by users on your site. In order to make it easier to create HTML encoded content, ASP.NET 4.0 introduces a new Expression syntax using <%: %> to encode string values. The encoding expression syntax looks like this: <%: "<script type='text/javascript'>" +     "alert('Really?');</script>" %> which produces properly encoded HTML: &lt;script type=&#39;text/javascript&#39; &gt;alert(&#39;Really?&#39;);&lt;/script&gt; Effectively this is a shortcut to: <%= HttpUtility.HtmlEncode( "<script type='text/javascript'>" + "alert('Really?');</script>") %> Of course the <%: %> syntax can also evaluate expressions just like <%= %> so the more common scenario applies this expression syntax against data your application is displaying. Here’s an example displaying some data model values: <%: Model.Address.Street %> This snippet shows displaying data from your application’s data store or more importantly, from data entered by users. Anything that makes it easier and less verbose to HtmlEncode text is a welcome addition to avoid potential cross-site scripting attacks. Although I listed Inline HTML Encoding here under WebForms, anything that uses the WebForms rendering engine including ASP.NET MVC, benefits from this feature. ScriptManager Enhancements The ASP.NET ScriptManager control in the past has introduced some nice ways to take programmatic and markup control over script loading, but there were a number of shortcomings in this control. The ASP.NET 4.0 ScriptManager has a number of improvements that make it easier to control script loading and addresses a few of the shortcomings that have often kept me from using the control in favor of manual script loading. The first is the AjaxFrameworkMode property which finally lets you suppress loading the ASP.NET AJAX runtime. Disabled doesn’t load any ASP.NET AJAX libraries, but there’s also an Explicit mode that lets you pick and choose the library pieces individually and reduce the footprint of ASP.NET AJAX script included if you are using the library. There’s also a new EnableCdn property that forces any script that has a new WebResource attribute CdnPath property set to a CDN supplied URL. If the script has this Attribute property set to a non-null/empty value and EnableCdn is enabled on the ScriptManager, that script will be served from the specified CdnPath. [assembly: WebResource(    "Westwind.Web.Resources.ww.jquery.js",    "application/x-javascript",    CdnPath =  "http://mysite.com/scripts/ww.jquery.min.js")] Cool, but a little too static for my taste since this value can’t be changed at runtime to point at a debug script as needed, for example. Assembly names for loading scripts from resources can now be simple names rather than fully qualified assembly names, which make it less verbose to reference scripts from assemblies loaded from your bin folder or the assembly reference area in web.config: <asp:ScriptManager runat="server" id="Id"          EnableCdn="true"         AjaxFrameworkMode="disabled">     <Scripts>         <asp:ScriptReference          Name="Westwind.Web.Resources.ww.jquery.js"         Assembly="Westwind.Web" />     </Scripts>        </asp:ScriptManager> The ScriptManager in 4.0 also supports script combining via the CompositeScript tag, which allows you to very easily combine scripts into a single script resource served via ASP.NET. Even nicer: You can specify the URL that the combined script is served with. Check out the following script manager markup that combines several static file scripts and a script resource into a single ASP.NET served resource from a static URL (allscripts.js): <asp:ScriptManager runat="server" id="Id"          EnableCdn="true"         AjaxFrameworkMode="disabled">     <CompositeScript          Path="~/scripts/allscripts.js">         <Scripts>             <asp:ScriptReference                    Path="~/scripts/jquery.js" />             <asp:ScriptReference                    Path="~/scripts/ww.jquery.js" />             <asp:ScriptReference            Name="Westwind.Web.Resources.editors.js"                 Assembly="Westwind.Web" />         </Scripts>     </CompositeScript> </asp:ScriptManager> When you render this into HTML, you’ll see a single script reference in the page: <script src="scripts/allscripts.debug.js"          type="text/javascript"></script> All you need to do to make this work is ensure that allscripts.js and allscripts.debug.js exist in the scripts folder of your application - they can be empty but the file has to be there. This is pretty cool, but you want to be real careful that you use unique URLs for each combination of scripts you combine or else browser and server caching will easily screw you up royally. The script manager also allows you to override native ASP.NET AJAX scripts now as any script references defined in the Scripts section of the ScriptManager trump internal references. So if you want custom behavior or you want to fix a possible bug in the core libraries that normally are loaded from resources, you can now do this simply by referencing the script resource name in the Name property and pointing at System.Web for the assembly. Not a common scenario, but when you need it, it can come in real handy. Still, there are a number of shortcomings in this control. For one, the ScriptManager and ClientScript APIs still have no common entry point so control developers are still faced with having to check and support both APIs to load scripts so that controls can work on pages that do or don’t have a ScriptManager on the page. The CdnUrl is static and compiled in, which is very restrictive. And finally, there’s still no control over where scripts get loaded on the page - ScriptManager still injects scripts into the middle of the HTML markup rather than in the header or optionally the footer. This, in turn, means there is little control over script loading order, which can be problematic for control developers. MetaDescription, MetaKeywords Page Properties There are also a number of additional Page properties that correspond to some of the other features discussed in this column: ClientIDMode, ClientTarget and ViewStateMode. Another minor but useful feature is that you can now directly access the MetaDescription and MetaKeywords properties on the Page object to set the corresponding meta tags programmatically. Updating these values programmatically previously required either <%= %> expressions in the page markup or dynamic insertion of literal controls into the page. You can now just set these properties programmatically on the Page object in any Control derived class on the page or the Page itself: Page.MetaKeywords = "ASP.NET,4.0,New Features"; Page.MetaDescription = "This article discusses the new features in ASP.NET 4.0"; Note, that there’s no corresponding ASP.NET tag for the HTML Meta element, so the only way to specify these values in markup and access them is via the @Page tag: <%@Page Language="C#"      CodeBehind="WebForm2.aspx.cs"     Inherits="Westwind.WebStore.WebForm2"      ClientIDMode="Static"                MetaDescription="Article that discusses what's                      new in ASP.NET 4.0"     MetaKeywords="ASP.NET,4.0,New Features" %> Nothing earth shattering but quite convenient. Visual Studio 2010 Enhancements for Web Development For Web development there are also a host of editor enhancements in Visual Studio 2010. Some of these are not Web specific but they are useful for Web developers in general. Text Editors Throughout Visual Studio 2010, the text editors have all been updated to a new core engine based on WPF which provides some interesting new features for various code editors including the nice ability to zoom in and out with Ctrl-MouseWheel to quickly change the size of text. There are many more API options to control the editor and although Visual Studio 2010 doesn’t yet use many of these features, we can look forward to enhancements in add-ins and future editor updates from the various language teams that take advantage of the visual richness that WPF provides to editing. On the negative side, I’ve noticed that occasionally the code editor and especially the HTML and JavaScript editors will lose the ability to use various navigation keys like arrows, back and delete keys, which requires closing and reopening the documents at times. This issue seems to be well documented so I suspect this will be addressed soon with a hotfix or within the first service pack. Overall though, the code editors work very well, especially given that they were re-written completely using WPF, which was one of my big worries when I first heard about the complete redesign of the editors. Multi-Targeting Visual Studio now targets all versions of the .NET framework from 2.0 forward. You can use Visual Studio 2010 to work on your ASP.NET 2, 3.0 and 3.5 applications which is a nice way to get your feet wet with the new development environment without having to make changes to existing applications. It’s nice to have one tool to work in for all the different versions. Multi-Monitor Support One cool feature of Visual Studio 2010 is the ability to drag windows out of the Visual Studio environment and out onto the desktop including onto another monitor easily. Since Web development often involves working with a host of designers at the same time - visual designer, HTML markup window, code behind and JavaScript editor - it’s really nice to be able to have a little more screen real estate to work on each of these editors. Microsoft made a welcome change in the environment. IntelliSense Snippets for HTML and JavaScript Editors The HTML and JavaScript editors now finally support IntelliSense scripts to create macro-based template expansions that have been in the core C# and Visual Basic code editors since Visual Studio 2005. Snippets allow you to create short XML-based template definitions that can act as static macros or real templates that can have replaceable values that can be embedded into the expanded text. The XML syntax for these snippets is straight forward and it’s pretty easy to create custom snippets manually. You can easily create snippets using XML and store them in your custom snippets folder (C:\Users\rstrahl\Documents\Visual Studio 2010\Code Snippets\Visual Web Developer\My HTML Snippets and My JScript Snippets), but it helps to use one of the third-party tools that exist to simplify the process for you. I use SnippetEditor, by Bill McCarthy, which makes short work of creating snippets interactively (http://snippeteditor.codeplex.com/). Note: You may have to manually add the Visual Studio 2010 User specific Snippet folders to this tool to see existing ones you’ve created. Code snippets are some of the biggest time savers and HTML editing more than anything deals with lots of repetitive tasks that lend themselves to text expansion. Visual Studio 2010 includes a slew of built-in snippets (that you can also customize!) and you can create your own very easily. If you haven’t done so already, I encourage you to spend a little time examining your coding patterns and find the repetitive code that you write and convert it into snippets. I’ve been using CodeRush for this for years, but now you can do much of the basic expansion natively for HTML and JavaScript snippets. jQuery Integration Is Now Native jQuery is a popular JavaScript library and recently Microsoft has recently stated that it will become the primary client-side scripting technology to drive higher level script functionality in various ASP.NET Web projects that Microsoft provides. In Visual Studio 2010, the default full project template includes jQuery as part of a new project including the support files that provide IntelliSense (-vsdoc files). IntelliSense support for jQuery is now also baked into Visual Studio 2010, so unlike Visual Studio 2008 which required a separate download, no further installs are required for a rich IntelliSense experience with jQuery. Summary ASP.NET 4.0 brings many useful improvements to the platform, but thankfully most of the changes are incremental changes that don’t compromise backwards compatibility and they allow developers to ease into the new features one feature at a time. None of the changes in ASP.NET 4.0 or Visual Studio 2010 are monumental or game changers. The bigger features are language and .NET Framework changes that are also optional. This ASP.NET and tools release feels more like fine tuning and getting some long-standing kinks worked out of the platform. It shows that the ASP.NET team is dedicated to paying attention to community feedback and responding with changes to the platform and development environment based on this feedback. If you haven’t gotten your feet wet with ASP.NET 4.0 and Visual Studio 2010, there’s no reason not to give it a shot now - the ASP.NET 4.0 platform is solid and Visual Studio 2010 works very well for a brand new release. Check it out. © Rick Strahl, West Wind Technologies, 2005-2010Posted in ASP.NET  

    Read the article

  • LVM / Device Mapper maps wrong device

    - by DaDaDom
    Hi, I run a LVM setup on a raid1 created by mdadm. md2 is based on sda6 (major:minor 8:6) and sdb6 (8:22). md2 is partition 9:2. The VG on top of md2 has 4 LVs, var, home, usr, tmp. First the problem: While booting it seems as if the device mapper takes the wrong partition for the mapping! Immediately after boot the information is like ~# dmsetup table systemlvm-home: 0 4194304 linear 8:22 384 systemlvm-home: 4194304 16777216 linear 8:22 69206400 systemlvm-home: 20971520 8388608 linear 8:22 119538048 systemlvm-home: 29360128 6291456 linear 8:22 243270016 systemlvm-tmp: 0 2097152 linear 8:22 41943424 systemlvm-usr: 0 10485760 linear 8:22 20971904 systemlvm-var: 0 10485760 linear 8:22 10486144 systemlvm-var: 10485760 6291456 linear 8:22 4194688 systemlvm-var: 16777216 4194304 linear 8:22 44040576 systemlvm-var: 20971520 10485760 linear 8:22 31457664 systemlvm-var: 31457280 20971520 linear 8:22 48234880 systemlvm-var: 52428800 33554432 linear 8:22 85983616 systemlvm-var: 85983232 115343360 linear 8:22 127926656 ~# cat /proc/mdstat Personalities : [raid1] md2 : active (auto-read-only) raid1 sda6[0] 151798080 blocks [2/1] [U_] md0 : active raid1 sda1[0] sdb1[1] 96256 blocks [2/2] [UU] md1 : active raid1 sda2[0] sdb2[1] 2931776 blocks [2/2] [UU] I have to manually "lvchange -an" all LVs, add /dev/sdb6 back to the raid and reactivate the LVs, then all is fine. But it prevents me from automounting the partitions and obviously leads to a bunch of other problems. If everything works fine, the information is like ~$ cat /proc/mdstat Personalities : [raid1] md2 : active raid1 sdb6[1] sda6[0] 151798080 blocks [2/2] [UU] ... ~# dmsetup table systemlvm-home: 0 4194304 linear 9:2 384 systemlvm-home: 4194304 16777216 linear 9:2 69206400 systemlvm-home: 20971520 8388608 linear 9:2 119538048 systemlvm-home: 29360128 6291456 linear 9:2 243270016 systemlvm-tmp: 0 2097152 linear 9:2 41943424 systemlvm-usr: 0 10485760 linear 9:2 20971904 systemlvm-var: 0 10485760 linear 9:2 10486144 systemlvm-var: 10485760 6291456 linear 9:2 4194688 systemlvm-var: 16777216 4194304 linear 9:2 44040576 systemlvm-var: 20971520 10485760 linear 9:2 31457664 systemlvm-var: 31457280 20971520 linear 9:2 48234880 systemlvm-var: 52428800 33554432 linear 9:2 85983616 systemlvm-var: 85983232 115343360 linear 9:2 127926656 I think that LVM for some reason just "takes" /dev/sdb6 which is then missing in the raid. I tried almost all options in the lvm.conf but none seems to work. Below is some more information, like config files. Does anyone have any idea about what is going on here and how to prevent that? If you need any additional information, please let me know Thanks in advance! Dominik The information (off a "repaired" system): ~# cat /etc/debian_version 5.0.4 ~# uname -a Linux kermit 2.6.26-2-686 #1 SMP Wed Feb 10 08:59:21 UTC 2010 i686 GNU/Linux ~# lvm version LVM version: 2.02.39 (2008-06-27) Library version: 1.02.27 (2008-06-25) Driver version: 4.13.0 ~# cat /etc/mdadm/mdadm.conf DEVICE partitions ARRAY /dev/md1 level=raid1 num-devices=2 metadata=00.90 UUID=11e9dc6c:1da99f3f:b3088ca6:c6fe60e9 ARRAY /dev/md0 level=raid1 num-devices=2 metadata=00.90 UUID=92ed1e4b:897361d3:070682b3:3baa4fa1 ARRAY /dev/md2 level=raid1 num-devices=2 metadata=00.90 UUID=601d4642:39dc80d7:96e8bbac:649924ba ~# mount /dev/md1 on / type ext3 (rw,errors=remount-ro) tmpfs on /lib/init/rw type tmpfs (rw,nosuid,mode=0755) proc on /proc type proc (rw,noexec,nosuid,nodev) sysfs on /sys type sysfs (rw,noexec,nosuid,nodev) procbususb on /proc/bus/usb type usbfs (rw) udev on /dev type tmpfs (rw,mode=0755) tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev) devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=620) /dev/md0 on /boot type ext3 (rw) /dev/mapper/systemlvm-usr on /usr type reiserfs (rw) /dev/mapper/systemlvm-tmp on /tmp type reiserfs (rw) /dev/mapper/systemlvm-home on /home type reiserfs (rw) /dev/mapper/systemlvm-var on /var type reiserfs (rw) ~# grep -v ^$ /etc/lvm/lvm.conf | grep -v "#" devices { dir = "/dev" scan = [ "/dev" ] preferred_names = [ ] filter = [ "a|/dev/md.*|", "r/.*/" ] cache_dir = "/etc/lvm/cache" cache_file_prefix = "" write_cache_state = 1 sysfs_scan = 1 md_component_detection = 1 ignore_suspended_devices = 0 } log { verbose = 0 syslog = 1 overwrite = 0 level = 0 indent = 1 command_names = 0 prefix = " " } backup { backup = 1 backup_dir = "/etc/lvm/backup" archive = 1 archive_dir = "/etc/lvm/archive" retain_min = 10 retain_days = 30 } shell { history_size = 100 } global { umask = 077 test = 0 units = "h" activation = 1 proc = "/proc" locking_type = 1 fallback_to_clustered_locking = 1 fallback_to_local_locking = 1 locking_dir = "/lib/init/rw" } activation { missing_stripe_filler = "/dev/ioerror" reserved_stack = 256 reserved_memory = 8192 process_priority = -18 mirror_region_size = 512 readahead = "auto" mirror_log_fault_policy = "allocate" mirror_device_fault_policy = "remove" } :~# vgscan -vvv Processing: vgscan -vvv O_DIRECT will be used Setting global/locking_type to 1 File-based locking selected. Setting global/locking_dir to /lib/init/rw Locking /lib/init/rw/P_global WB Wiping cache of LVM-capable devices /dev/block/1:0: Added to device cache /dev/block/1:1: Added to device cache /dev/block/1:10: Added to device cache /dev/block/1:11: Added to device cache /dev/block/1:12: Added to device cache /dev/block/1:13: Added to device cache /dev/block/1:14: Added to device cache /dev/block/1:15: Added to device cache /dev/block/1:2: Added to device cache /dev/block/1:3: Added to device cache /dev/block/1:4: Added to device cache /dev/block/1:5: Added to device cache /dev/block/1:6: Added to device cache /dev/block/1:7: Added to device cache /dev/block/1:8: Added to device cache /dev/block/1:9: Added to device cache /dev/block/253:0: Added to device cache /dev/block/253:1: Added to device cache /dev/block/253:2: Added to device cache /dev/block/253:3: Added to device cache /dev/block/8:0: Added to device cache /dev/block/8:1: Added to device cache /dev/block/8:16: Added to device cache /dev/block/8:17: Added to device cache /dev/block/8:18: Added to device cache /dev/block/8:19: Added to device cache /dev/block/8:2: Added to device cache /dev/block/8:21: Added to device cache /dev/block/8:22: Added to device cache /dev/block/8:3: Added to device cache /dev/block/8:5: Added to device cache /dev/block/8:6: Added to device cache /dev/block/9:0: Already in device cache /dev/block/9:1: Already in device cache /dev/block/9:2: Already in device cache /dev/bsg/0:0:0:0: Not a block device /dev/bsg/1:0:0:0: Not a block device /dev/bus/usb/001/001: Not a block device [... many more "not a block device"] /dev/core: Not a block device /dev/cpu_dma_latency: Not a block device /dev/disk/by-id/ata-SAMSUNG_HD160JJ_S08HJ10L507895: Aliased to /dev/block/8:16 in device cache /dev/disk/by-id/ata-SAMSUNG_HD160JJ_S08HJ10L507895-part1: Aliased to /dev/block/8:17 in device cache /dev/disk/by-id/ata-SAMSUNG_HD160JJ_S08HJ10L507895-part2: Aliased to /dev/block/8:18 in device cache /dev/disk/by-id/ata-SAMSUNG_HD160JJ_S08HJ10L507895-part3: Aliased to /dev/block/8:19 in device cache /dev/disk/by-id/ata-SAMSUNG_HD160JJ_S08HJ10L507895-part5: Aliased to /dev/block/8:21 in device cache /dev/disk/by-id/ata-SAMSUNG_HD160JJ_S08HJ10L507895-part6: Aliased to /dev/block/8:22 in device cache /dev/disk/by-id/ata-SAMSUNG_HD160JJ_S08HJ10L526800: Aliased to /dev/block/8:0 in device cache /dev/disk/by-id/ata-SAMSUNG_HD160JJ_S08HJ10L526800-part1: Aliased to /dev/block/8:1 in device cache /dev/disk/by-id/ata-SAMSUNG_HD160JJ_S08HJ10L526800-part2: Aliased to /dev/block/8:2 in device cache /dev/disk/by-id/ata-SAMSUNG_HD160JJ_S08HJ10L526800-part3: Aliased to /dev/block/8:3 in device cache /dev/disk/by-id/ata-SAMSUNG_HD160JJ_S08HJ10L526800-part5: Aliased to /dev/block/8:5 in device cache /dev/disk/by-id/ata-SAMSUNG_HD160JJ_S08HJ10L526800-part6: Aliased to /dev/block/8:6 in device cache /dev/disk/by-id/dm-name-systemlvm-home: Aliased to /dev/block/253:2 in device cache /dev/disk/by-id/dm-name-systemlvm-tmp: Aliased to /dev/block/253:3 in device cache /dev/disk/by-id/dm-name-systemlvm-usr: Aliased to /dev/block/253:1 in device cache /dev/disk/by-id/dm-name-systemlvm-var: Aliased to /dev/block/253:0 in device cache /dev/disk/by-id/dm-uuid-LVM-rL8Oq2dA7oeRYeu1orJA7Ufnb1kjOyvr25N7CRZpUMzR18NfS6zeSeAVnVT98LuU: Aliased to /dev/block/253:0 in device cache /dev/disk/by-id/dm-uuid-LVM-rL8Oq2dA7oeRYeu1orJA7Ufnb1kjOyvr3TpFXtLjYGEwn79IdXsSCZPl8AxmqbmQ: Aliased to /dev/block/253:1 in device cache /dev/disk/by-id/dm-uuid-LVM-rL8Oq2dA7oeRYeu1orJA7Ufnb1kjOyvrc5MJ4KolevMjt85PPBrQuRTkXbx6NvTi: Aliased to /dev/block/253:3 in device cache /dev/disk/by-id/dm-uuid-LVM-rL8Oq2dA7oeRYeu1orJA7Ufnb1kjOyvrYXrfdg5OSYDVkNeiQeQksgCI849Z2hx8: Aliased to /dev/block/253:2 in device cache /dev/disk/by-id/md-uuid-11e9dc6c:1da99f3f:b3088ca6:c6fe60e9: Already in device cache /dev/disk/by-id/md-uuid-601d4642:39dc80d7:96e8bbac:649924ba: Already in device cache /dev/disk/by-id/md-uuid-92ed1e4b:897361d3:070682b3:3baa4fa1: Already in device cache /dev/disk/by-id/scsi-SATA_SAMSUNG_HD160JJS08HJ10L507895: Aliased to /dev/block/8:16 in device cache /dev/disk/by-id/scsi-SATA_SAMSUNG_HD160JJS08HJ10L507895-part1: Aliased to /dev/block/8:17 in device cache /dev/disk/by-id/scsi-SATA_SAMSUNG_HD160JJS08HJ10L507895-part2: Aliased to /dev/block/8:18 in device cache /dev/disk/by-id/scsi-SATA_SAMSUNG_HD160JJS08HJ10L507895-part3: Aliased to /dev/block/8:19 in device cache /dev/disk/by-id/scsi-SATA_SAMSUNG_HD160JJS08HJ10L507895-part5: Aliased to /dev/block/8:21 in device cache /dev/disk/by-id/scsi-SATA_SAMSUNG_HD160JJS08HJ10L507895-part6: Aliased to /dev/block/8:22 in device cache /dev/disk/by-id/scsi-SATA_SAMSUNG_HD160JJS08HJ10L526800: Aliased to /dev/block/8:0 in device cache /dev/disk/by-id/scsi-SATA_SAMSUNG_HD160JJS08HJ10L526800-part1: Aliased to /dev/block/8:1 in device cache /dev/disk/by-id/scsi-SATA_SAMSUNG_HD160JJS08HJ10L526800-part2: Aliased to /dev/block/8:2 in device cache /dev/disk/by-id/scsi-SATA_SAMSUNG_HD160JJS08HJ10L526800-part3: Aliased to /dev/block/8:3 in device cache /dev/disk/by-id/scsi-SATA_SAMSUNG_HD160JJS08HJ10L526800-part5: Aliased to /dev/block/8:5 in device cache /dev/disk/by-id/scsi-SATA_SAMSUNG_HD160JJS08HJ10L526800-part6: Aliased to /dev/block/8:6 in device cache /dev/disk/by-path/pci-0000:00:0f.0-scsi-0:0:0:0: Aliased to /dev/block/8:0 in device cache /dev/disk/by-path/pci-0000:00:0f.0-scsi-0:0:0:0-part1: Aliased to /dev/block/8:1 in device cache /dev/disk/by-path/pci-0000:00:0f.0-scsi-0:0:0:0-part2: Aliased to /dev/block/8:2 in device cache /dev/disk/by-path/pci-0000:00:0f.0-scsi-0:0:0:0-part3: Aliased to /dev/block/8:3 in device cache /dev/disk/by-path/pci-0000:00:0f.0-scsi-0:0:0:0-part5: Aliased to /dev/block/8:5 in device cache /dev/disk/by-path/pci-0000:00:0f.0-scsi-0:0:0:0-part6: Aliased to /dev/block/8:6 in device cache /dev/disk/by-path/pci-0000:00:0f.0-scsi-1:0:0:0: Aliased to /dev/block/8:16 in device cache /dev/disk/by-path/pci-0000:00:0f.0-scsi-1:0:0:0-part1: Aliased to /dev/block/8:17 in device cache /dev/disk/by-path/pci-0000:00:0f.0-scsi-1:0:0:0-part2: Aliased to /dev/block/8:18 in device cache /dev/disk/by-path/pci-0000:00:0f.0-scsi-1:0:0:0-part3: Aliased to /dev/block/8:19 in device cache /dev/disk/by-path/pci-0000:00:0f.0-scsi-1:0:0:0-part5: Aliased to /dev/block/8:21 in device cache /dev/disk/by-path/pci-0000:00:0f.0-scsi-1:0:0:0-part6: Aliased to /dev/block/8:22 in device cache /dev/disk/by-uuid/13c1262b-e06f-40ce-b088-ce410640a6dc: Aliased to /dev/block/253:3 in device cache /dev/disk/by-uuid/379f57b0-2e03-414c-808a-f76160617336: Aliased to /dev/block/253:2 in device cache /dev/disk/by-uuid/4fb2d6d3-bd51-48d3-95ee-8e404faf243d: Already in device cache /dev/disk/by-uuid/5c6728ec-82c1-49c0-93c5-f6dbd5c0d659: Aliased to /dev/block/8:5 in device cache /dev/disk/by-uuid/a13cdfcd-2191-4185-a727-ffefaf7a382e: Aliased to /dev/block/253:1 in device cache /dev/disk/by-uuid/e0d5893d-ff88-412f-b753-9e3e9af3242d: Aliased to /dev/block/8:21 in device cache /dev/disk/by-uuid/e79c9da6-8533-4e55-93ec-208876671edc: Aliased to /dev/block/253:0 in device cache /dev/disk/by-uuid/f3f176f5-12f7-4af8-952a-c6ac43a6e332: Already in device cache /dev/dm-0: Aliased to /dev/block/253:0 in device cache (preferred name) /dev/dm-1: Aliased to /dev/block/253:1 in device cache (preferred name) /dev/dm-2: Aliased to /dev/block/253:2 in device cache (preferred name) /dev/dm-3: Aliased to /dev/block/253:3 in device cache (preferred name) /dev/fd: Symbolic link to directory /dev/full: Not a block device /dev/hpet: Not a block device /dev/initctl: Not a block device /dev/input/by-path/platform-i8042-serio-0-event-kbd: Not a block device /dev/input/event0: Not a block device /dev/input/mice: Not a block device /dev/kmem: Not a block device /dev/kmsg: Not a block device /dev/log: Not a block device /dev/loop/0: Added to device cache /dev/MAKEDEV: Not a block device /dev/mapper/control: Not a block device /dev/mapper/systemlvm-home: Aliased to /dev/dm-2 in device cache /dev/mapper/systemlvm-tmp: Aliased to /dev/dm-3 in device cache /dev/mapper/systemlvm-usr: Aliased to /dev/dm-1 in device cache /dev/mapper/systemlvm-var: Aliased to /dev/dm-0 in device cache /dev/md0: Already in device cache /dev/md1: Already in device cache /dev/md2: Already in device cache /dev/mem: Not a block device /dev/net/tun: Not a block device /dev/network_latency: Not a block device /dev/network_throughput: Not a block device /dev/null: Not a block device /dev/port: Not a block device /dev/ppp: Not a block device /dev/psaux: Not a block device /dev/ptmx: Not a block device /dev/pts/0: Not a block device /dev/ram0: Aliased to /dev/block/1:0 in device cache (preferred name) /dev/ram1: Aliased to /dev/block/1:1 in device cache (preferred name) /dev/ram10: Aliased to /dev/block/1:10 in device cache (preferred name) /dev/ram11: Aliased to /dev/block/1:11 in device cache (preferred name) /dev/ram12: Aliased to /dev/block/1:12 in device cache (preferred name) /dev/ram13: Aliased to /dev/block/1:13 in device cache (preferred name) /dev/ram14: Aliased to /dev/block/1:14 in device cache (preferred name) /dev/ram15: Aliased to /dev/block/1:15 in device cache (preferred name) /dev/ram2: Aliased to /dev/block/1:2 in device cache (preferred name) /dev/ram3: Aliased to /dev/block/1:3 in device cache (preferred name) /dev/ram4: Aliased to /dev/block/1:4 in device cache (preferred name) /dev/ram5: Aliased to /dev/block/1:5 in device cache (preferred name) /dev/ram6: Aliased to /dev/block/1:6 in device cache (preferred name) /dev/ram7: Aliased to /dev/block/1:7 in device cache (preferred name) /dev/ram8: Aliased to /dev/block/1:8 in device cache (preferred name) /dev/ram9: Aliased to /dev/block/1:9 in device cache (preferred name) /dev/random: Not a block device /dev/root: Already in device cache /dev/rtc: Not a block device /dev/rtc0: Not a block device /dev/sda: Aliased to /dev/block/8:0 in device cache (preferred name) /dev/sda1: Aliased to /dev/block/8:1 in device cache (preferred name) /dev/sda2: Aliased to /dev/block/8:2 in device cache (preferred name) /dev/sda3: Aliased to /dev/block/8:3 in device cache (preferred name) /dev/sda5: Aliased to /dev/block/8:5 in device cache (preferred name) /dev/sda6: Aliased to /dev/block/8:6 in device cache (preferred name) /dev/sdb: Aliased to /dev/block/8:16 in device cache (preferred name) /dev/sdb1: Aliased to /dev/block/8:17 in device cache (preferred name) /dev/sdb2: Aliased to /dev/block/8:18 in device cache (preferred name) /dev/sdb3: Aliased to /dev/block/8:19 in device cache (preferred name) /dev/sdb5: Aliased to /dev/block/8:21 in device cache (preferred name) /dev/sdb6: Aliased to /dev/block/8:22 in device cache (preferred name) /dev/shm/network/ifstate: Not a block device /dev/snapshot: Not a block device /dev/sndstat: stat failed: Datei oder Verzeichnis nicht gefunden /dev/stderr: Not a block device /dev/stdin: Not a block device /dev/stdout: Not a block device /dev/systemlvm/home: Aliased to /dev/dm-2 in device cache /dev/systemlvm/tmp: Aliased to /dev/dm-3 in device cache /dev/systemlvm/usr: Aliased to /dev/dm-1 in device cache /dev/systemlvm/var: Aliased to /dev/dm-0 in device cache /dev/tty: Not a block device /dev/tty0: Not a block device [... many more "not a block device"] /dev/vcsa6: Not a block device /dev/xconsole: Not a block device /dev/zero: Not a block device Wiping internal VG cache lvmcache: initialised VG #orphans_lvm1 lvmcache: initialised VG #orphans_pool lvmcache: initialised VG #orphans_lvm2 Reading all physical volumes. This may take a while... Finding all volume groups /dev/ram0: Skipping (regex) /dev/loop/0: Skipping (sysfs) /dev/sda: Skipping (regex) Opened /dev/md0 RO /dev/md0: size is 192512 sectors Closed /dev/md0 /dev/md0: size is 192512 sectors Opened /dev/md0 RW O_DIRECT /dev/md0: block size is 1024 bytes Closed /dev/md0 Using /dev/md0 Opened /dev/md0 RW O_DIRECT /dev/md0: block size is 1024 bytes /dev/md0: No label detected Closed /dev/md0 /dev/dm-0: Skipping (regex) /dev/ram1: Skipping (regex) /dev/sda1: Skipping (regex) Opened /dev/md1 RO /dev/md1: size is 5863552 sectors Closed /dev/md1 /dev/md1: size is 5863552 sectors Opened /dev/md1 RW O_DIRECT /dev/md1: block size is 4096 bytes Closed /dev/md1 Using /dev/md1 Opened /dev/md1 RW O_DIRECT /dev/md1: block size is 4096 bytes /dev/md1: No label detected Closed /dev/md1 /dev/dm-1: Skipping (regex) /dev/ram2: Skipping (regex) /dev/sda2: Skipping (regex) Opened /dev/md2 RO /dev/md2: size is 303596160 sectors Closed /dev/md2 /dev/md2: size is 303596160 sectors Opened /dev/md2 RW O_DIRECT /dev/md2: block size is 4096 bytes Closed /dev/md2 Using /dev/md2 Opened /dev/md2 RW O_DIRECT /dev/md2: block size is 4096 bytes /dev/md2: lvm2 label detected lvmcache: /dev/md2: now in VG #orphans_lvm2 (#orphans_lvm2) /dev/md2: Found metadata at 39936 size 2632 (in area at 2048 size 194560) for systemlvm (rL8Oq2-dA7o-eRYe-u1or-JA7U-fnb1-kjOyvr) lvmcache: /dev/md2: now in VG systemlvm with 1 mdas lvmcache: /dev/md2: setting systemlvm VGID to rL8Oq2dA7oeRYeu1orJA7Ufnb1kjOyvr lvmcache: /dev/md2: VG systemlvm: Set creation host to rescue. Closed /dev/md2 /dev/dm-2: Skipping (regex) /dev/ram3: Skipping (regex) /dev/sda3: Skipping (regex) /dev/dm-3: Skipping (regex) /dev/ram4: Skipping (regex) /dev/ram5: Skipping (regex) /dev/sda5: Skipping (regex) /dev/ram6: Skipping (regex) /dev/sda6: Skipping (regex) /dev/ram7: Skipping (regex) /dev/ram8: Skipping (regex) /dev/ram9: Skipping (regex) /dev/ram10: Skipping (regex) /dev/ram11: Skipping (regex) /dev/ram12: Skipping (regex) /dev/ram13: Skipping (regex) /dev/ram14: Skipping (regex) /dev/ram15: Skipping (regex) /dev/sdb: Skipping (regex) /dev/sdb1: Skipping (regex) /dev/sdb2: Skipping (regex) /dev/sdb3: Skipping (regex) /dev/sdb5: Skipping (regex) /dev/sdb6: Skipping (regex) Locking /lib/init/rw/V_systemlvm RB Finding volume group "systemlvm" Opened /dev/md2 RW O_DIRECT /dev/md2: block size is 4096 bytes /dev/md2: lvm2 label detected lvmcache: /dev/md2: now in VG #orphans_lvm2 (#orphans_lvm2) with 1 mdas /dev/md2: Found metadata at 39936 size 2632 (in area at 2048 size 194560) for systemlvm (rL8Oq2-dA7o-eRYe-u1or-JA7U-fnb1-kjOyvr) lvmcache: /dev/md2: now in VG systemlvm with 1 mdas lvmcache: /dev/md2: setting systemlvm VGID to rL8Oq2dA7oeRYeu1orJA7Ufnb1kjOyvr lvmcache: /dev/md2: VG systemlvm: Set creation host to rescue. Using cached label for /dev/md2 Read systemlvm metadata (19) from /dev/md2 at 39936 size 2632 /dev/md2 0: 0 16: home(0:0) /dev/md2 1: 16 24: var(40:0) /dev/md2 2: 40 40: var(0:0) /dev/md2 3: 80 40: usr(0:0) /dev/md2 4: 120 40: var(80:0) /dev/md2 5: 160 8: tmp(0:0) /dev/md2 6: 168 16: var(64:0) /dev/md2 7: 184 80: var(120:0) /dev/md2 8: 264 64: home(16:0) /dev/md2 9: 328 128: var(200:0) /dev/md2 10: 456 32: home(80:0) /dev/md2 11: 488 440: var(328:0) /dev/md2 12: 928 24: home(112:0) /dev/md2 13: 952 206: NULL(0:0) Found volume group "systemlvm" using metadata type lvm2 Read volume group systemlvm from /etc/lvm/backup/systemlvm Unlocking /lib/init/rw/V_systemlvm Closed /dev/md2 Unlocking /lib/init/rw/P_global ~# vgdisplay --- Volume group --- VG Name systemlvm System ID Format lvm2 Metadata Areas 1 Metadata Sequence No 19 VG Access read/write VG Status resizable MAX LV 0 Cur LV 4 Open LV 4 Max PV 0 Cur PV 1 Act PV 1 VG Size 144,75 GB PE Size 128,00 MB Total PE 1158 Alloc PE / Size 952 / 119,00 GB Free PE / Size 206 / 25,75 GB VG UUID rL8Oq2-dA7o-eRYe-u1or-JA7U-fnb1-kjOyvr ~# pvdisplay --- Physical volume --- PV Name /dev/md2 VG Name systemlvm PV Size 144,77 GB / not usable 16,31 MB Allocatable yes PE Size (KByte) 131072 Total PE 1158 Free PE 206 Allocated PE 952 PV UUID ZSAzP5-iBvr-L7jy-wB8T-AiWz-0g3m-HLK66Y :~# lvdisplay --- Logical volume --- LV Name /dev/systemlvm/home VG Name systemlvm LV UUID YXrfdg-5OSY-DVkN-eiQe-Qksg-CI84-9Z2hx8 LV Write Access read/write LV Status available # open 2 LV Size 17,00 GB Current LE 136 Segments 4 Allocation inherit Read ahead sectors auto - currently set to 256 Block device 253:2 --- Logical volume --- LV Name /dev/systemlvm/var VG Name systemlvm LV UUID 25N7CR-ZpUM-zR18-NfS6-zeSe-AVnV-T98LuU LV Write Access read/write LV Status available # open 2 LV Size 96,00 GB Current LE 768 Segments 7 Allocation inherit Read ahead sectors auto - currently set to 256 Block device 253:0 --- Logical volume --- LV Name /dev/systemlvm/usr VG Name systemlvm LV UUID 3TpFXt-LjYG-Ewn7-9IdX-sSCZ-Pl8A-xmqbmQ LV Write Access read/write LV Status available # open 2 LV Size 5,00 GB Current LE 40 Segments 1 Allocation inherit Read ahead sectors auto - currently set to 256 Block device 253:1 --- Logical volume --- LV Name /dev/systemlvm/tmp VG Name systemlvm LV UUID c5MJ4K-olev-Mjt8-5PPB-rQuR-TkXb-x6NvTi LV Write Access read/write LV Status available # open 2 LV Size 1,00 GB Current LE 8 Segments 1 Allocation inherit Read ahead sectors auto - currently set to 256 Block device 253:3

    Read the article

  • App cannot start at all in Android 2.2 (Froyo)

    - by Roland Lim
    Dear fellow Android developers & Google Engineers, My app has been running okay until the recent Froyo update. After installing the Android 2.2 SDK, I can compile my code without any errors. However, when I run it, it just force closes: Here's the log: 05-23 10:15:13.463: DEBUG/AndroidRuntime(423): >>>>>>>>>>>>>> AndroidRuntime START <<<<<<<<<<<<<< 05-23 10:15:13.463: DEBUG/AndroidRuntime(423): CheckJNI is ON 05-23 10:15:14.193: DEBUG/AndroidRuntime(423): --- registering native functions --- 05-23 10:15:15.293: DEBUG/AndroidRuntime(423): Shutting down VM 05-23 10:15:15.303: DEBUG/dalvikvm(423): Debugger has detached; object registry had 1 entries 05-23 10:15:15.333: INFO/AndroidRuntime(423): NOTE: attach of thread 'Binder Thread #3' failed 05-23 10:15:16.003: DEBUG/AndroidRuntime(431): >>>>>>>>>>>>>> AndroidRuntime START <<<<<<<<<<<<<< 05-23 10:15:16.013: DEBUG/AndroidRuntime(431): CheckJNI is ON 05-23 10:15:16.273: DEBUG/AndroidRuntime(431): --- registering native functions --- 05-23 10:15:17.392: INFO/ActivityManager(59): Starting activity: Intent { act=android.intent.action.MAIN cat= [android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.handyapps.easymoney/.EasyMoney } 05-23 10:15:17.602: DEBUG/AndroidRuntime(431): Shutting down VM 05-23 10:15:17.662: DEBUG/dalvikvm(431): Debugger has detached; object registry had 1 entries 05-23 10:15:17.742: INFO/AndroidRuntime(431): NOTE: attach of thread 'Binder Thread #3' failed 05-23 10:15:17.912: INFO/ActivityManager(59): Start proc com.handyapps.easymoney for activity com.handyapps.easymoney/.EasyMoney: pid=438 uid=10035 gids={1006, 1015} 05-23 10:15:19.032: DEBUG/AndroidRuntime(438): Shutting down VM 05-23 10:15:19.032: WARN/dalvikvm(438): threadid=1: thread exiting with uncaught exception (group=0x4001d800) 05-23 10:15:19.062: ERROR/AndroidRuntime(438): FATAL EXCEPTION: main 05-23 10:15:19.062: ERROR/AndroidRuntime(438): java.lang.RuntimeException: Unable to instantiate application com.handyapps.easymoney.EasyMoney: java.lang.ClassCastException: com.handyapps.easymoney.EasyMoney 05-23 10:15:19.062: ERROR/AndroidRuntime(438): at android.app.ActivityThread$PackageInfo.makeApplication (ActivityThread.java:649) 05-23 10:15:19.062: ERROR/AndroidRuntime(438): at android.app.ActivityThread.handleBindApplication (ActivityThread.java:4232) 05-23 10:15:19.062: ERROR/AndroidRuntime(438): at android.app.ActivityThread.access$3000(ActivityThread.java:125) 05-23 10:15:19.062: ERROR/AndroidRuntime(438): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2071) 05-23 10:15:19.062: ERROR/AndroidRuntime(438): at android.os.Handler.dispatchMessage(Handler.java:99) 05-23 10:15:19.062: ERROR/AndroidRuntime(438): at android.os.Looper.loop(Looper.java:123) 05-23 10:15:19.062: ERROR/AndroidRuntime(438): at android.app.ActivityThread.main(ActivityThread.java:4627) 05-23 10:15:19.062: ERROR/AndroidRuntime(438): at java.lang.reflect.Method.invokeNative(Native Method) 05-23 10:15:19.062: ERROR/AndroidRuntime(438): at java.lang.reflect.Method.invoke(Method.java:521) 05-23 10:15:19.062: ERROR/AndroidRuntime(438): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:868) 05-23 10:15:19.062: ERROR/AndroidRuntime(438): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 05-23 10:15:19.062: ERROR/AndroidRuntime(438): at dalvik.system.NativeStart.main(Native Method) 05-23 10:15:19.062: ERROR/AndroidRuntime(438): Caused by: java.lang.ClassCastException: com.handyapps.easymoney.EasyMoney 05-23 10:15:19.062: ERROR/AndroidRuntime(438): at android.app.Instrumentation.newApplication(Instrumentation.java:957) 05-23 10:15:19.062: ERROR/AndroidRuntime(438): at android.app.Instrumentation.newApplication(Instrumentation.java:942) 05-23 10:15:19.062: ERROR/AndroidRuntime(438): at android.app.ActivityThread$PackageInfo.makeApplication (ActivityThread.java:644) 05-23 10:15:19.062: ERROR/AndroidRuntime(438): ... 11 more 05-23 10:15:19.082: WARN/ActivityManager(59): Force finishing activity com.handyapps.easymoney/.EasyMoney 05-23 10:15:19.592: WARN/ActivityManager(59): Activity pause timeout for HistoryRecord{450018f0 com.handyapps.easymoney/.EasyMoney} //////////////THE ANDROID MANIFEST FILE//// <uses-permission android:name="android.permission.READ_PHONE_STATE"/> <uses-permission android:name="android.permission.CAMERA"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-feature android:name="android.hardware.camera" /> <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="4" /> <application android:icon="@drawable/icon" android:name="@string/app_name" android:label="@string/app_name" android:debuggable="false"> <activity android:name=".EasyMoney" android:label="@string/app_name" android:theme="@android:style/Theme.NoTitleBar" android:launchMode="singleTask" android:clearTaskOnLaunch="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".TranList" android:label="@string/app_name" android:theme="@android:style/Theme.Light.NoTitleBar"/> <activity android:name=".TranEdit" android:theme="@android:style/Theme.Light.NoTitleBar" android:windowSoftInputMode="stateAlwaysHidden"/> <activity android:name=".BillReminderEdit" android:theme="@android:style/Theme.Light.NoTitleBar" android:windowSoftInputMode="stateAlwaysHidden"/> <activity android:name=".BillReminderList" android:launchMode="singleTop" android:theme="@android:style/Theme.Light.NoTitleBar"/> <activity android:name=".BudgetList" android:theme="@android:style/Theme.Light.NoTitleBar"/> <activity android:name=".BudgetEdit" android:theme="@android:style/Theme.Light.NoTitleBar" android:windowSoftInputMode="stateAlwaysHidden"/> <activity android:name=".Search" android:theme="@style/CustomDialogTheme" android:windowSoftInputMode="stateAlwaysHidden"/> <activity android:name=".PasscodeEntry" android:theme="@style/CustomDialogTheme" android:windowSoftInputMode="stateAlwaysHidden" android:screenOrientation="portrait"/> <activity android:name=".AccountList" android:theme="@android:style/Theme.Light.NoTitleBar"> </activity> <activity android:name=".AccountEdit" android:theme="@android:style/Theme.Light.NoTitleBar" android:windowSoftInputMode="stateAlwaysHidden"/> <activity android:name=".UserSettingsEdit" android:theme="@android:style/Theme.Light.NoTitleBar" android:windowSoftInputMode="stateAlwaysHidden"/> <activity android:name=".CurrencySettingsEdit" android:theme="@android:style/Theme.Light.NoTitleBar" android:windowSoftInputMode="stateAlwaysHidden"/> <activity android:name=".DisplaySettingsEdit" android:theme="@android:style/Theme.Light.NoTitleBar" android:windowSoftInputMode="stateAlwaysHidden"/> <activity android:name=".BackupSettingsEdit" android:theme="@android:style/Theme.Light.NoTitleBar" android:windowSoftInputMode="stateAlwaysHidden"/> <activity android:name=".CategoryList" android:theme="@android:style/Theme.Light.NoTitleBar" /> <activity android:name=".CategoryEdit" android:theme="@android:style/Theme.Light.NoTitleBar" android:windowSoftInputMode="stateAlwaysHidden"/> <activity android:name=".ExpenseByCategory" android:theme="@android:style/Theme.Light.NoTitleBar"/> <activity android:name=".BalanceReport" android:theme="@android:style/Theme.Light.NoTitleBar"/> <activity android:name=".MonthlyExpenseReport" android:theme="@android:style/Theme.Light.NoTitleBar"/> <activity android:name=".MonthlyIncomeReport" android:theme="@android:style/Theme.Light.NoTitleBar"/> <activity android:name=".MonthlyCashflowReport" android:theme="@android:style/Theme.Light.NoTitleBar"/> <activity android:name=".PhotoList" android:theme="@android:style/Theme.Light.NoTitleBar" /> <activity android:name=".ExpenseByPayee" android:theme="@android:style/Theme.Light.NoTitleBar"/> <activity android:name=".ExpenseBySubCategory" android:theme="@android:style/Theme.Light.NoTitleBar"/> <service android:name="StartAlarm_Service"> <intent-filter> <action android:name="com.handyapps.easymoney.StartAlarm_Service" /> </intent-filter> </service> <service android:name=".AlarmService_Service" android:process=":remote" /> <receiver android:name="StartupIntentReceiver"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> <category android:name="android.intent.category.HOME" /> </intent-filter> </receiver> <receiver android:name=".WidgetProvider" android:label="@string/widget_name"> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> </intent-filter> <meta-data android:name="android.appwidget.provider" android:resource="@xml/widget" /> </receiver> <receiver android:name=".WidgetProvider" android:label="@string/widget_name"> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> <data android:scheme="easymoney_widget" /> </intent-filter> <meta-data android:name="android.appwidget.provider" android:resource="@xml/widget" /> </receiver> <receiver android:name=".WidgetProvider"> <intent-filter> <action android:name="com.handyapps.easymoney.WIDGET_CONTROL" /> <data android:scheme="easymoney_widget" /> </intent-filter> </receiver> </application> The main startup class is com.handyapps.easymoney.EasyMoney. I placed a breakpoint at the start of the onCreate() method but I discovered it didn't even reach there. Somehow, the application just couldn't be loaded in Android 2.2... but it works perfectly fine for all the previous Android versions. Been trying to find the cause for the past 2 days but am totally stumped!! Any help will be greatly appreciated!!!! Thanks!! Roland

    Read the article

  • how to export bind and keyframe bone poses from blender to use in OpenGL

    - by SaldaVonSchwartz
    EDIT: I decided to reformulate the question in much simpler terms to see if someone can give me a hand with this. Basically, I'm exporting meshes, skeletons and actions from blender into an engine of sorts that I'm working on. But I'm getting the animations wrong. I can tell the basic motion paths are being followed but there's always an axis of translation or rotation which is wrong. I think the problem is most likely not in my engine code (OpenGL-based) but rather in either my misunderstanding of some part of the theory behind skeletal animation / skinning or the way I am exporting the appropriate joint matrices from blender in my exporter script. I'll explain the theory, the engine animation system and my blender export script, hoping someone might catch the error in either or all of these. The theory: (I'm using column-major ordering since that's what I use in the engine cause it's OpenGL-based) Assume I have a mesh made up of a single vertex v, along with a transformation matrix M which takes the vertex v from the mesh's local space to world space. That is, if I was to render the mesh without a skeleton, the final position would be gl_Position = ProjectionMatrix * M * v. Now assume I have a skeleton with a single joint j in bind / rest pose. j is actually another matrix. A transform from j's local space to its parent space which I'll denote Bj. if j was part of a joint hierarchy in the skeleton, Bj would take from j space to j-1 space (that is to its parent space). However, in this example j is the only joint, so Bj takes from j space to world space, like M does for v. Now further assume I have a a set of frames, each with a second transform Cj, which works the same as Bj only that for a different, arbitrary spatial configuration of join j. Cj still takes vertices from j space to world space but j is rotated and/or translated and/or scaled. Given the above, in order to skin vertex v at keyframe n. I need to: take v from world space to joint j space modify j (while v stays fixed in j space and is thus taken along in the transformation) take v back from the modified j space to world space So the mathematical implementation of the above would be: v' = Cj * Bj^-1 * v. Actually, I have one doubt here.. I said the mesh to which v belongs has a transform M which takes from model space to world space. And I've also read in a couple textbooks that it needs to be transformed from model space to joint space. But I also said in 1 that v needs to be transformed from world to joint space. So basically I'm not sure if I need to do v' = Cj * Bj^-1 * v or v' = Cj * Bj^-1 * M * v. Right now my implementation multiples v' by M and not v. But I've tried changing this and it just screws things up in a different way cause there's something else wrong. Finally, If we wanted to skin a vertex to a joint j1 which in turn is a child of a joint j0, Bj1 would be Bj0 * Bj1 and Cj1 would be Cj0 * Cj1. But Since skinning is defined as v' = Cj * Bj^-1 * v , Bj1^-1 would be the reverse concatenation of the inverses making up the original product. That is, v' = Cj0 * Cj1 * Bj1^-1 * Bj0^-1 * v Now on to the implementation (Blender side): Assume the following mesh made up of 1 cube, whose vertices are bound to a single joint in a single-joint skeleton: Assume also there's a 60-frame, 3-keyframe animation at 60 fps. The animation essentially is: keyframe 0: the joint is in bind / rest pose (the way you see it in the image). keyframe 30: the joint translates up (+z in blender) some amount and at the same time rotates pi/4 rad clockwise. keyframe 59: the joint goes back to the same configuration it was in keyframe 0. My first source of confusion on the blender side is its coordinate system (as opposed to OpenGL's default) and the different matrices accessible through the python api. Right now, this is what my export script does about translating blender's coordinate system to OpenGL's standard system: # World transform: Blender -> OpenGL worldTransform = Matrix().Identity(4) worldTransform *= Matrix.Scale(-1, 4, (0,0,1)) worldTransform *= Matrix.Rotation(radians(90), 4, "X") # Mesh (local) transform matrix file.write('Mesh Transform:\n') localTransform = mesh.matrix_local.copy() localTransform = worldTransform * localTransform for col in localTransform.col: file.write('{:9f} {:9f} {:9f} {:9f}\n'.format(col[0], col[1], col[2], col[3])) file.write('\n') So if you will, my "world" matrix is basically the act of changing blenders coordinate system to the default GL one with +y up, +x right and -z into the viewing volume. Then I also premultiply (in the sense that it's done by the time we reach the engine, not in the sense of post or pre in terms of matrix multiplication order) the mesh matrix M so that I don't need to multiply it again once per draw call in the engine. About the possible matrices to extract from Blender joints (bones in Blender parlance), I'm doing the following: For joint bind poses: def DFSJointTraversal(file, skeleton, jointList): for joint in jointList: bindPoseJoint = skeleton.data.bones[joint.name] bindPoseTransform = bindPoseJoint.matrix_local.inverted() file.write('Joint ' + joint.name + ' Transform {\n') translationV = bindPoseTransform.to_translation() rotationQ = bindPoseTransform.to_3x3().to_quaternion() scaleV = bindPoseTransform.to_scale() file.write('T {:9f} {:9f} {:9f}\n'.format(translationV[0], translationV[1], translationV[2])) file.write('Q {:9f} {:9f} {:9f} {:9f}\n'.format(rotationQ[1], rotationQ[2], rotationQ[3], rotationQ[0])) file.write('S {:9f} {:9f} {:9f}\n'.format(scaleV[0], scaleV[1], scaleV[2])) DFSJointTraversal(file, skeleton, joint.children) file.write('}\n') Note that I'm actually grabbing the inverse of what I think is the bind pose transform Bj. This is so I don't need to invert it in the engine. Also note I went for matrix_local, assuming this is Bj. The other option is plain "matrix", which as far as I can tell is the same only that not homogeneous. For joint current / keyframe poses: for kfIndex in keyframes: bpy.context.scene.frame_set(kfIndex) file.write('keyframe: {:d}\n'.format(int(kfIndex))) for i in range(0, len(skeleton.data.bones)): file.write('joint: {:d}\n'.format(i)) currentPoseJoint = skeleton.pose.bones[i] currentPoseTransform = currentPoseJoint.matrix translationV = currentPoseTransform.to_translation() rotationQ = currentPoseTransform.to_3x3().to_quaternion() scaleV = currentPoseTransform.to_scale() file.write('T {:9f} {:9f} {:9f}\n'.format(translationV[0], translationV[1], translationV[2])) file.write('Q {:9f} {:9f} {:9f} {:9f}\n'.format(rotationQ[1], rotationQ[2], rotationQ[3], rotationQ[0])) file.write('S {:9f} {:9f} {:9f}\n'.format(scaleV[0], scaleV[1], scaleV[2])) file.write('\n') Note that here I go for skeleton.pose.bones instead of data.bones and that I have a choice of 3 matrices: matrix, matrix_basis and matrix_channel. From the descriptions in the python API docs I'm not super clear which one I should choose, though I think it's the plain matrix. Also note I do not invert the matrix in this case. The implementation (Engine / OpenGL side): My animation subsystem does the following on each update (I'm omitting parts of the update loop where it's figured out which objects need update and time is hardcoded here for simplicity): static double time = 0; time = fmod((time + elapsedTime),1.); uint16_t LERPKeyframeNumber = 60 * time; uint16_t lkeyframeNumber = 0; uint16_t lkeyframeIndex = 0; uint16_t rkeyframeNumber = 0; uint16_t rkeyframeIndex = 0; for (int i = 0; i < aClip.keyframesCount; i++) { uint16_t keyframeNumber = aClip.keyframes[i].number; if (keyframeNumber <= LERPKeyframeNumber) { lkeyframeIndex = i; lkeyframeNumber = keyframeNumber; } else { rkeyframeIndex = i; rkeyframeNumber = keyframeNumber; break; } } double lTime = lkeyframeNumber / 60.; double rTime = rkeyframeNumber / 60.; double blendFactor = (time - lTime) / (rTime - lTime); GLKMatrix4 bindPosePalette[aSkeleton.jointsCount]; GLKMatrix4 currentPosePalette[aSkeleton.jointsCount]; for (int i = 0; i < aSkeleton.jointsCount; i++) { F3DETQSType& lPose = aClip.keyframes[lkeyframeIndex].skeletonPose.joints[i]; F3DETQSType& rPose = aClip.keyframes[rkeyframeIndex].skeletonPose.joints[i]; GLKVector3 LERPTranslation = GLKVector3Lerp(lPose.t, rPose.t, blendFactor); GLKQuaternion SLERPRotation = GLKQuaternionSlerp(lPose.q, rPose.q, blendFactor); GLKVector3 LERPScaling = GLKVector3Lerp(lPose.s, rPose.s, blendFactor); GLKMatrix4 currentTransform = GLKMatrix4MakeWithQuaternion(SLERPRotation); currentTransform = GLKMatrix4TranslateWithVector3(currentTransform, LERPTranslation); currentTransform = GLKMatrix4ScaleWithVector3(currentTransform, LERPScaling); GLKMatrix4 inverseBindTransform = GLKMatrix4MakeWithQuaternion(aSkeleton.joints[i].inverseBindTransform.q); inverseBindTransform = GLKMatrix4TranslateWithVector3(inverseBindTransform, aSkeleton.joints[i].inverseBindTransform.t); inverseBindTransform = GLKMatrix4ScaleWithVector3(inverseBindTransform, aSkeleton.joints[i].inverseBindTransform.s); if (aSkeleton.joints[i].parentIndex == -1) { bindPosePalette[i] = inverseBindTransform; currentPosePalette[i] = currentTransform; } else { bindPosePalette[i] = GLKMatrix4Multiply(inverseBindTransform, bindPosePalette[aSkeleton.joints[i].parentIndex]); currentPosePalette[i] = GLKMatrix4Multiply(currentPosePalette[aSkeleton.joints[i].parentIndex], currentTransform); } aSkeleton.skinningPalette[i] = GLKMatrix4Multiply(currentPosePalette[i], bindPosePalette[i]); } Finally, this is my vertex shader: #version 100 uniform mat4 modelMatrix; uniform mat3 normalMatrix; uniform mat4 projectionMatrix; uniform mat4 skinningPalette[6]; uniform lowp float skinningEnabled; attribute vec4 position; attribute vec3 normal; attribute vec2 tCoordinates; attribute vec4 jointsWeights; attribute vec4 jointsIndices; varying highp vec2 tCoordinatesVarying; varying highp float lIntensity; void main() { tCoordinatesVarying = tCoordinates; vec4 skinnedVertexPosition = vec4(0.); for (int i = 0; i < 4; i++) { skinnedVertexPosition += jointsWeights[i] * skinningPalette[int(jointsIndices[i])] * position; } vec4 skinnedNormal = vec4(0.); for (int i = 0; i < 4; i++) { skinnedNormal += jointsWeights[i] * skinningPalette[int(jointsIndices[i])] * vec4(normal, 0.); } vec4 finalPosition = mix(position, skinnedVertexPosition, skinningEnabled); vec4 finalNormal = mix(vec4(normal, 0.), skinnedNormal, skinningEnabled); vec3 eyeNormal = normalize(normalMatrix * finalNormal.xyz); vec3 lightPosition = vec3(0., 0., 2.); lIntensity = max(0.0, dot(eyeNormal, normalize(lightPosition))); gl_Position = projectionMatrix * modelMatrix * finalPosition; } The result is that the animation displays wrong in terms of orientation. That is, instead of bobbing up and down it bobs in and out (along what I think is the Z axis according to my transform in the export clip). And the rotation angle is counterclockwise instead of clockwise. If I try with a more than one joint, then it's almost as if the second joint rotates in it's own different coordinate space and does not follow 100% its parent's transform. Which I assume it should from my animation subsystem which I assume in turn follows the theory I explained for the case of more than one joint. Any thoughts?

    Read the article

  • Setting up a pc bluetooth server for android

    - by Del
    Alright, I've been reading a lot of topics the past two or three days and nothing seems to have asked this. I am writing a PC side server for my andriod device, this is for exchanging some information and general debugging. Eventually I will be connecting to a SPP device to control a microcontroller. I have managed, using the following (Android to pc) to connect to rfcomm channel 11 and exchange data between my android device and my pc. Method m = device.getClass().getMethod("createRfcommSocket", new Class[] { int.class }); tmp = (BluetoothSocket) m.invoke(device, Integer.valueOf(11)); I have attempted the createRfcommSocketToServiceRecord(UUID) method, with absolutely no luck. For the PC side, I have been using the C Bluez stack for linux. I have the following code which registers the service and opens a server socket: int main(int argc, char **argv) { struct sockaddr_rc loc_addr = { 0 }, rem_addr = { 0 }; char buf[1024] = { 0 }; char str[1024] = { 0 }; int s, client, bytes_read; sdp_session_t *session; socklen_t opt = sizeof(rem_addr); session = register_service(); s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); loc_addr.rc_family = AF_BLUETOOTH; loc_addr.rc_bdaddr = *BDADDR_ANY; loc_addr.rc_channel = (uint8_t) 11; bind(s, (struct sockaddr *)&loc_addr, sizeof(loc_addr)); listen(s, 1); client = accept(s, (struct sockaddr *)&rem_addr, &opt); ba2str( &rem_addr.rc_bdaddr, buf ); fprintf(stderr, "accepted connection from %s\n", buf); memset(buf, 0, sizeof(buf)); bytes_read = read(client, buf, sizeof(buf)); if( bytes_read 0 ) { printf("received [%s]\n", buf); } sprintf(str,"to Android."); printf("sent [%s]\n",str); write(client, str, sizeof(str)); close(client); close(s); sdp_close( session ); return 0; } sdp_session_t *register_service() { uint32_t svc_uuid_int[] = { 0x00000000,0x00000000,0x00000000,0x00000000 }; uint8_t rfcomm_channel = 11; const char *service_name = "Remote Host"; const char *service_dsc = "What the remote should be connecting to."; const char *service_prov = "Your mother"; uuid_t root_uuid, l2cap_uuid, rfcomm_uuid, svc_uuid; sdp_list_t *l2cap_list = 0, *rfcomm_list = 0, *root_list = 0, *proto_list = 0, *access_proto_list = 0; sdp_data_t *channel = 0, *psm = 0; sdp_record_t *record = sdp_record_alloc(); // set the general service ID sdp_uuid128_create( &svc_uuid, &svc_uuid_int ); sdp_set_service_id( record, svc_uuid ); // make the service record publicly browsable sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root_list = sdp_list_append(0, &root_uuid); sdp_set_browse_groups( record, root_list ); // set l2cap information sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); l2cap_list = sdp_list_append( 0, &l2cap_uuid ); proto_list = sdp_list_append( 0, l2cap_list ); // set rfcomm information sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); channel = sdp_data_alloc(SDP_UINT8, &rfcomm_channel); rfcomm_list = sdp_list_append( 0, &rfcomm_uuid ); sdp_list_append( rfcomm_list, channel ); sdp_list_append( proto_list, rfcomm_list ); // attach protocol information to service record access_proto_list = sdp_list_append( 0, proto_list ); sdp_set_access_protos( record, access_proto_list ); // set the name, provider, and description sdp_set_info_attr(record, service_name, service_prov, service_dsc); int err = 0; sdp_session_t *session = 0; // connect to the local SDP server, register the service record, and // disconnect session = sdp_connect( BDADDR_ANY, BDADDR_LOCAL, SDP_RETRY_IF_BUSY ); err = sdp_record_register(session, record, 0); // cleanup //sdp_data_free( channel ); sdp_list_free( l2cap_list, 0 ); sdp_list_free( rfcomm_list, 0 ); sdp_list_free( root_list, 0 ); sdp_list_free( access_proto_list, 0 ); return session; } And another piece of code, in addition to 'sdptool browse local' which can verifty that the service record is running on the pc: int main(int argc, char **argv) { uuid_t svc_uuid; uint32_t svc_uuid_int[] = { 0x00000000,0x00000000,0x00000000,0x00000000 }; int err; bdaddr_t target; sdp_list_t *response_list = NULL, *search_list, *attrid_list; sdp_session_t *session = 0; str2ba( "01:23:45:67:89:AB", &target ); // connect to the SDP server running on the remote machine session = sdp_connect( BDADDR_ANY, BDADDR_LOCAL, SDP_RETRY_IF_BUSY ); // specify the UUID of the application we're searching for sdp_uuid128_create( &svc_uuid, &svc_uuid_int ); search_list = sdp_list_append( NULL, &svc_uuid ); // specify that we want a list of all the matching applications' attributes uint32_t range = 0x0000ffff; attrid_list = sdp_list_append( NULL, &range ); // get a list of service records that have UUID 0xabcd err = sdp_service_search_attr_req( session, search_list, \ SDP_ATTR_REQ_RANGE, attrid_list, &response_list); sdp_list_t *r = response_list; // go through each of the service records for (; r; r = r-next ) { sdp_record_t *rec = (sdp_record_t*) r-data; sdp_list_t *proto_list; // get a list of the protocol sequences if( sdp_get_access_protos( rec, &proto_list ) == 0 ) { sdp_list_t *p = proto_list; // go through each protocol sequence for( ; p ; p = p-next ) { sdp_list_t *pds = (sdp_list_t*)p-data; // go through each protocol list of the protocol sequence for( ; pds ; pds = pds-next ) { // check the protocol attributes sdp_data_t *d = (sdp_data_t*)pds-data; int proto = 0; for( ; d; d = d-next ) { switch( d-dtd ) { case SDP_UUID16: case SDP_UUID32: case SDP_UUID128: proto = sdp_uuid_to_proto( &d-val.uuid ); break; case SDP_UINT8: if( proto == RFCOMM_UUID ) { printf("rfcomm channel: %d\n",d-val.int8); } break; } } } sdp_list_free( (sdp_list_t*)p-data, 0 ); } sdp_list_free( proto_list, 0 ); } printf("found service record 0x%x\n", rec-handle); sdp_record_free( rec ); } sdp_close(session); } Output: $ ./search rfcomm channel: 11 found service record 0x10008 sdptool: Service Name: Remote Host Service Description: What the remote should be connecting to. Service Provider: Your mother Service RecHandle: 0x10008 Protocol Descriptor List: "L2CAP" (0x0100) "RFCOMM" (0x0003) Channel: 11 And for logcat I'm getting this: 07-22 15:57:06.087: ERROR/BTLD(215): ****************search UUID = 0000*********** 07-22 15:57:06.087: INFO//system/bin/btld(209): btapp_dm_GetRemoteServiceChannel() 07-22 15:57:06.087: INFO//system/bin/btld(209): ##### USerial_Ioctl: BT_Wake, 0x8003 #### 07-22 15:57:06.097: INFO/ActivityManager(88): Displayed activity com.example.socktest/.socktest: 79 ms (total 79 ms) 07-22 15:57:06.697: INFO//system/bin/btld(209): ##### USerial_Ioctl: BT_Sleep, 0x8004 #### 07-22 15:57:07.517: WARN/BTLD(215): ccb timer ticks: 2147483648 07-22 15:57:07.517: INFO//system/bin/btld(209): ##### USerial_Ioctl: BT_Wake, 0x8003 #### 07-22 15:57:07.547: WARN/BTLD(215): info:x10 07-22 15:57:07.547: INFO/BTL-IFS(215): send_ctrl_msg: [BTL_IFS CTRL] send BTLIF_DTUN_SIGNAL_EVT (CTRL) 10 pbytes (hdl 14) 07-22 15:57:07.547: DEBUG/DTUN_HCID_BZ4(253): dtun_dm_sig_link_up() 07-22 15:57:07.547: INFO/DTUN_HCID_BZ4(253): dtun_dm_sig_link_up: dummy_handle = 342 07-22 15:57:07.547: DEBUG/ADAPTER(253): adapter_get_device(00:02:72:AB:7C:EE) 07-22 15:57:07.547: ERROR/BluetoothEventLoop.cpp(88): pollData[0] is revented, check next one 07-22 15:57:07.547: ERROR/BluetoothEventLoop.cpp(88): event_filter: Received signal org.bluez.Device:PropertyChanged from /org/bluez/253/hci0/dev_00_02_72_AB_7C_EE 07-22 15:57:07.777: WARN/BTLD(215): process_service_search_attr_rsp 07-22 15:57:07.787: INFO/BTL-IFS(215): send_ctrl_msg: [BTL_IFS CTRL] send BTLIF_DTUN_SIGNAL_EVT (CTRL) 13 pbytes (hdl 14) 07-22 15:57:07.787: INFO/DTUN_HCID_BZ4(253): dtun_dm_sig_rmt_service_channel: success=0, service=00000000 07-22 15:57:07.787: ERROR/DTUN_HCID_BZ4(253): discovery unsuccessful! 07-22 15:57:08.497: INFO//system/bin/btld(209): ##### USerial_Ioctl: BT_Sleep, 0x8004 #### 07-22 15:57:09.507: INFO//system/bin/btld(209): ##### USerial_Ioctl: BT_Wake, 0x8003 #### 07-22 15:57:09.597: INFO/BTL-IFS(215): send_ctrl_msg: [BTL_IFS CTRL] send BTLIF_DTUN_SIGNAL_EVT (CTRL) 11 pbytes (hdl 14) 07-22 15:57:09.597: DEBUG/DTUN_HCID_BZ4(253): dtun_dm_sig_link_down() 07-22 15:57:09.597: INFO/DTUN_HCID_BZ4(253): dtun_dm_sig_link_down device = 0xf7a0 handle = 342 reason = 22 07-22 15:57:09.597: ERROR/BluetoothEventLoop.cpp(88): pollData[0] is revented, check next one 07-22 15:57:09.597: ERROR/BluetoothEventLoop.cpp(88): event_filter: Received signal org.bluez.Device:PropertyChanged from /org/bluez/253/hci0/dev_00_02_72_AB_7C_EE 07-22 15:57:09.597: DEBUG/BluetoothA2dpService(88): Received intent Intent { act=android.bluetooth.device.action.ACL_DISCONNECTED (has extras) } 07-22 15:57:10.107: INFO//system/bin/btld(209): ##### USerial_Ioctl: BT_Sleep, 0x8004 #### 07-22 15:57:12.107: DEBUG/BluetoothService(88): Cleaning up failed UUID channel lookup: 00:02:72:AB:7C:EE 00000000-0000-0000-0000-000000000000 07-22 15:57:12.107: ERROR/Socket Test(5234): connect() failed 07-22 15:57:12.107: DEBUG/ASOCKWRP(5234): asocket_abort [31,32,33] 07-22 15:57:12.107: INFO/BLZ20_WRAPPER(5234): blz20_wrp_shutdown: s 31, how 2 07-22 15:57:12.107: DEBUG/BLZ20_WRAPPER(5234): blz20_wrp_shutdown: fd (-1:31), bta -1, rc 0, wflags 0x0 07-22 15:57:12.107: INFO/BLZ20_WRAPPER(5234): __close_prot_rfcomm: fd 31 07-22 15:57:12.107: INFO/BLZ20_WRAPPER(5234): __close_prot_rfcomm: bind not completed on this socket 07-22 15:57:12.107: DEBUG/BLZ20_WRAPPER(5234): btlif_signal_event: fd (-1:31), bta -1, rc 0, wflags 0x0 07-22 15:57:12.107: DEBUG/BLZ20_WRAPPER(5234): btlif_signal_event: event BTLIF_BTS_EVT_ABORT matched 07-22 15:57:12.107: DEBUG/BTL_IFC_WRP(5234): wrp_close_s_only: wrp_close_s_only [31] (31:-1) [] 07-22 15:57:12.107: DEBUG/BTL_IFC_WRP(5234): wrp_close_s_only: data socket closed 07-22 15:57:12.107: DEBUG/BTL_IFC_WRP(5234): wsactive_del: delete wsock 31 from active list [ad3e1494] 07-22 15:57:12.107: DEBUG/BTL_IFC_WRP(5234): wrp_close_s_only: wsock fully closed, return to pool 07-22 15:57:12.107: DEBUG/BLZ20_WRAPPER(5234): btsk_free: success 07-22 15:57:12.107: DEBUG/BLZ20_WRAPPER(5234): blz20_wrp_write: wrote 1 bytes out of 1 on fd 33 07-22 15:57:12.107: DEBUG/ASOCKWRP(5234): asocket_destroy 07-22 15:57:12.107: DEBUG/ASOCKWRP(5234): asocket_abort [31,32,33] 07-22 15:57:12.107: INFO/BLZ20_WRAPPER(5234): blz20_wrp_shutdown: s 31, how 2 07-22 15:57:12.107: DEBUG/BLZ20_WRAPPER(5234): blz20_wrp_shutdown: btsk not found, normal close (31) 07-22 15:57:12.107: DEBUG/BLZ20_WRAPPER(5234): blz20_wrp_write: wrote 1 bytes out of 1 on fd 33 07-22 15:57:12.107: INFO/BLZ20_WRAPPER(5234): blz20_wrp_close: s 33 07-22 15:57:12.107: DEBUG/BLZ20_WRAPPER(5234): blz20_wrp_close: btsk not found, normal close (33) 07-22 15:57:12.107: INFO/BLZ20_WRAPPER(5234): blz20_wrp_close: s 32 07-22 15:57:12.107: DEBUG/BLZ20_WRAPPER(5234): blz20_wrp_close: btsk not found, normal close (32) 07-22 15:57:12.107: INFO/BLZ20_WRAPPER(5234): blz20_wrp_close: s 31 07-22 15:57:12.107: DEBUG/BLZ20_WRAPPER(5234): blz20_wrp_close: btsk not found, normal close (31) 07-22 15:57:12.157: DEBUG/Sensors(88): close_akm, fd=151 07-22 15:57:12.167: ERROR/CachedBluetoothDevice(477): onUuidChanged: Time since last connect14970690 07-22 15:57:12.237: DEBUG/Socket Test(5234): -On Stop- Sorry for bombarding you guys with what seems like a difficult question and a lot to read, but I've been working on this problem for a while and I've tried a lot of different things to get this working. Let me reiterate, I can get it to work, but not using service discovery protocol. I've tried a several different UUIDs and on two different computers, although I only have my HTC Incredible to test with. I've also heard some rumors that the BT stack wasn't working on the HTC Droid, but that isn't the case, at least, for PC interaction.

    Read the article

  • Android - BroadcastReceiver CONNECTIVITY ACTION

    - by Marc Ortiz
    in my project there's a service that listens for changes in the connectivity. When wifi is switched off to on then it gets called. The problem it's that i'm using a fragment and inside a fragment there's a button with the setonclicklistener(); and onclick(); SOMETIMES when i touch the button then the service receives an intent that the connectivity has changed (the method gets called without any reason...). Here's the code of my fragment activity for the viewpager layout: public static class FragmentSelection extends Fragment { int mNum; static FragmentSelection newInstance(int num) { FragmentSelection f = new FragmentSelection(); // Supply num input as an argument. Bundle args = new Bundle(); args.putInt("num", num); f.setArguments(args); return f; } /** * When creating, retrieve this instance's number from its arguments. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mNum = (getArguments() != null ? getArguments().getInt("num") : 1) + 1; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { final View v = inflater.inflate(R.layout.fragment_intro_contenido, container, false); Button btStart = (Button) v.findViewById(R.id.btChanged); final CheckBox cbSMS = (CheckBox) v.findViewById(R.id.checkBoxSms); final CheckBox cbCalls = (CheckBox) v .findViewById(R.id.checkBoxLlamadas); final CheckBox cbApps = (CheckBox) v .findViewById(R.id.checkBoxApps); final CheckBox cbPosition = (CheckBox) v .findViewById(R.id.checkBoxPosicion); final CheckBox cbContacts = (CheckBox) v .findViewById(R.id.checkBoxContactos); final CheckBox cbAll = (CheckBox) v.findViewById(R.id.checkBoxAll); cbSMS.setChecked(true); cbCalls.setChecked(true); cbApps.setChecked(true); cbPosition.setChecked(true); cbContacts.setChecked(true); cbAll.setChecked(true); btStart.setOnClickListener(new View.OnClickListener() { public void onClick(View c) { Intent i = new Intent(); i.setClass(v.getContext(), AnonymeActivity.class); if (!cbSMS.isChecked()) { i.putExtra("sms", 0); } else { i.putExtra("sms", 1); } if (!cbCalls.isChecked()) { i.putExtra("calls", 0); } else { i.putExtra("calls", 1); } if (cbContacts.isChecked()) { i.putExtra("contacts", 1); } else { i.putExtra("contacts", 0); } if (cbApps.isChecked()) { i.putExtra("apps", 1); } else { i.putExtra("apps", 0); } if (!cbPosition.isChecked()) { i.putExtra("gps", 0); } else { i.putExtra("gps", 1); } if (!cbAll.isChecked()) { if (cbSMS.isChecked() && cbCalls.isChecked() && cbContacts.isChecked() && cbApps.isChecked() && cbPosition.isChecked()) { i.putExtra("all", 1); } else { i.putExtra("all", 0); } } else { i.putExtra("all", 1); } startActivity(i); } }); return v; } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); } } My BroadcastReceiver class: class Broadcast_Reciver extends BroadcastReceiver implements Variables { CheckConexion cc; @Override public void onReceive(Context contxt, Intent intent) { // Cuando hay un evento, lo diferenciamos y hacemos una acción. if (intent.getAction().equals(SMS_RECEIVED)) { Sms sms = new Sms(null, contxt); sms.uploadNewSms(intent); } else if (intent.getAction().equals(Intent.ACTION_BATTERY_LOW)) { // st.batterylow(contxt); } else if (intent.getAction().equals(Intent.ACTION_POWER_CONNECTED)) { // st.power(1, contxt); } else if (intent.getAction().equals(Intent.ACTION_POWER_DISCONNECTED)) { // st.power(0, contxt); } else if (intent.getAction().equals(Intent.ACTION_CALL_BUTTON)) { // Notify } else if (intent.getAction().equals(Intent.ACTION_CAMERA_BUTTON)) { // Notify } else if (intent.getAction().equals(Intent.ACTION_PACKAGE_ADDED) || intent.getAction().equals(Intent.ACTION_PACKAGE_CHANGED) || intent.getAction().equals(Intent.ACTION_PACKAGE_REMOVED)) { Database db = new Database(contxt); if (db.open().Preferences(4)) { Uri data = intent.getData(); new ListApps(contxt).import_app(intent, contxt, data, intent.getAction()); } db.close(); } else if (intent.getAction().equals( ConnectivityManager.CONNECTIVITY_ACTION)) { cc = new CheckConexion(contxt); if (cc.isOnline()) { Database db = new Database(contxt); if (db.open().move() == 1) { new UploadOffline(contxt); } db.close(); } } } } And the errors: 9-03 23:20:37.887: E/SqliteDatabaseCpp(2715): CREATE TABLE android_metadata failed 09-03 23:20:37.887: E/SQLiteDatabase(2715): Failed to open the database. closing it. 09-03 23:20:37.887: E/SQLiteDatabase(2715): android.database.sqlite.SQLiteDatabaseLockedException: database is locked 09-03 23:20:37.887: E/SQLiteDatabase(2715): at android.database.sqlite.SQLiteDatabase.native_setLocale(Native Method) 09-03 23:20:37.887: E/SQLiteDatabase(2715): at android.database.sqlite.SQLiteDatabase.setLocale_(SQLiteDatabase.java:2211) 09-03 23:20:37.887: E/SQLiteDatabase(2715): at android.database.sqlite.SQLiteDatabase.setLocale(SQLiteDatabase.java:2199) 09-03 23:20:37.887: E/SQLiteDatabase(2715): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1130) 09-03 23:20:37.887: E/SQLiteDatabase(2715): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1081) 09-03 23:20:37.887: E/SQLiteDatabase(2715): at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:1167) 09-03 23:20:37.887: E/SQLiteDatabase(2715): at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:833) 09-03 23:20:37.887: E/SQLiteDatabase(2715): at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:221) 09-03 23:20:37.887: E/SQLiteDatabase(2715): at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:157) 09-03 23:20:37.887: E/SQLiteDatabase(2715): at com.background.Database.open(Database.java:127) 09-03 23:20:37.887: E/SQLiteDatabase(2715): at <b><b><b><h3>com.background.Broadcast_Reciver.onReceive(BroadcastService.java:100)</h3> 09-03 23:20:37.887: E/SQLiteDatabase(2715): at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:728) 09-03 23:20:37.887: E/SQLiteDatabase(2715): at android.os.Handler.handleCallback(Handler.java:605) 09-03 23:20:37.887: E/SQLiteDatabase(2715): at android.os.Handler.dispatchMessage(Handler.java:92) 09-03 23:20:37.887: E/SQLiteDatabase(2715): at android.os.Looper.loop(Looper.java:137) 09-03 23:20:37.887: E/SQLiteDatabase(2715): at android.app.ActivityThread.main(ActivityThread.java:4507) 09-03 23:20:37.887: E/SQLiteDatabase(2715): at java.lang.reflect.Method.invokeNative(Native Method) 09-03 23:20:37.887: E/SQLiteDatabase(2715): at java.lang.reflect.Method.invoke(Method.java:511) 09-03 23:20:37.887: E/SQLiteDatabase(2715): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790) 09-03 23:20:37.887: E/SQLiteDatabase(2715): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557) 09-03 23:20:37.887: E/SQLiteDatabase(2715): at dalvik.system.NativeStart.main(Native Method) 09-03 23:20:37.887: D/AndroidRuntime(2715): Shutting down VM 09-03 23:20:37.887: W/dalvikvm(2715): threadid=1: thread exiting with uncaught exception (group=0x40c3b1f8) 09-03 23:20:37.902: E/AndroidRuntime(2715): FATAL EXCEPTION: main 09-03 23:20:37.902: E/AndroidRuntime(2715): java.lang.RuntimeException: Error receiving broadcast Intent { act=android.net.conn.CONNECTIVITY_CHANGE flg=0x10000010 (has extras) } in com.background.Broadcast_Reciver@415203f8 09-03 23:20:37.902: E/AndroidRuntime(2715): at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:737) 09-03 23:20:37.902: E/AndroidRuntime(2715): at android.os.Handler.handleCallback(Handler.java:605) 09-03 23:20:37.902: E/AndroidRuntime(2715): at android.os.Handler.dispatchMessage(Handler.java:92) 09-03 23:20:37.902: E/AndroidRuntime(2715): at android.os.Looper.loop(Looper.java:137) 09-03 23:20:37.902: E/AndroidRuntime(2715): at android.app.ActivityThread.main(ActivityThread.java:4507) 09-03 23:20:37.902: E/AndroidRuntime(2715): at java.lang.reflect.Method.invokeNative(Native Method) 09-03 23:20:37.902: E/AndroidRuntime(2715): at java.lang.reflect.Method.invoke(Method.java:511) 09-03 23:20:37.902: E/AndroidRuntime(2715): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790) 09-03 23:20:37.902: E/AndroidRuntime(2715): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557) 09-03 23:20:37.902: E/AndroidRuntime(2715): at dalvik.system.NativeStart.main(Native Method) 09-03 23:20:37.902: E/AndroidRuntime(2715): Caused by: android.database.sqlite.SQLiteDatabaseLockedException: database is locked 09-03 23:20:37.902: E/AndroidRuntime(2715): at android.database.sqlite.SQLiteDatabase.native_setLocale(Native Method) 09-03 23:20:37.902: E/AndroidRuntime(2715): at android.database.sqlite.SQLiteDatabase.setLocale_(SQLiteDatabase.java:2211) 09-03 23:20:37.902: E/AndroidRuntime(2715): at android.database.sqlite.SQLiteDatabase.setLocale(SQLiteDatabase.java:2199) 09-03 23:20:37.902: E/AndroidRuntime(2715): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1130) 09-03 23:20:37.902: E/AndroidRuntime(2715): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1081) 09-03 23:20:37.902: E/AndroidRuntime(2715): at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:1167) 09-03 23:20:37.902: E/AndroidRuntime(2715): at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:833) 09-03 23:20:37.902: E/AndroidRuntime(2715): at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:221) 09-03 23:20:37.902: E/AndroidRuntime(2715): at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:157) 09-03 23:20:37.902: E/AndroidRuntime(2715): at com.background.Database.open(Database.java:127) 09-03 23:20:37.902: E/AndroidRuntime(2715): at com.background.Broadcast_Reciver.onReceive(BroadcastService.java:100) 09-03 23:20:37.902: E/AndroidRuntime(2715): at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:728) 09-03 23:20:37.902: E/AndroidRuntime(2715): ... 9 more Checkout that the program goes into BroadcastReceiver class and i don't understand why!

    Read the article

  • form not identifying the new input fields generated through a javascript

    - by tibin mathew
    Hi, I am developing a site in php. i have some issues with my form i have to more than one software packages at a time. so i have used javascript to append file and a dropdown to my html. i have called ajs function to add the new input fields each time when i click a link. and its displaying correctly. but its not identifying in my action page. i cant take the value of new input fields which i have created through that javascript function. below is the code page which i have used. function addInput(divName){ var newsel= document.createElement('div'); newsel.innerHTML="Operating System: --Select OS--    bc_linux    Linux   Solaris   2000/XP/Vista   XP/Vista   2K/XP/Vista/W7   HP   Windows 2000/XP/Vista zip   Windows 2000/XP/Vista exe   X Server - 2.2M   Fonts - 32.9M"; document.getElementById(divName).appendChild(newsel); var newdiv = document.createElement('div'); newdiv.innerHTML = "Upload Software File: "; document.getElementById(divName).appendChild(newdiv); } <form action="act-add-software.php" method="post" onSubmit="return validate(this);" enctype="multipart/form-data">  Operating System:  Operating System: <select name="frm_os" class="text_area" style="width:200px"> <option value="">--Select OS--</option> <optgroup label="Spind Enabled"> </optgroup> <option value="bc_linux">&nbsp;&nbsp;&nbsp;bc_linux</option> <optgroup label="Packages"> </optgroup> <option value="Linux">&nbsp;&nbsp;&nbsp;Linux</option> <option value="Solaris">&nbsp;&nbsp;&nbsp;Solaris</option> <option value="2000/XP/Vista">&nbsp;&nbsp;&nbsp;2000/XP/Vista</option> <option value="XP/Vista">&nbsp;&nbsp;&nbsp;XP/Vista</option> <option value="2K/XP/Vista/W7">&nbsp;&nbsp;&nbsp;2K/XP/Vista/W7</option> <option value="HP">&nbsp;&nbsp;&nbsp;HP</option> <option value="Windows 2000/XP/Vista zip">&nbsp;&nbsp;&nbsp;Windows 2000/XP/Vista zip</option> <option value="Windows 2000/XP/Vista exe">&nbsp;&nbsp;&nbsp;Windows 2000/XP/Vista exe</option> <option value="X Server - 2.2M">&nbsp;&nbsp;&nbsp;X Server - 2.2M</option> <option value="Fonts - 32.9M">&nbsp;&nbsp;&nbsp;Fonts - 32.9M</option> </select> <a onClick="addInput('dynamicInput');">Add More Package</a> </td> </td> </tr> <tr> <td colspan="2"><table border="0" cellpadding="0" cellspacing="0"> <tr align="center" valign="middle" class="tbl_row1"> <td height="25" align="left" class="font1" width="156" bgcolor="White"><div align="right"> <?if(strstr($frm_server_side_error,'frm_software')){?> <font class="error"><b> <font color="#dd0000">*</font>&nbsp;Upload Software File: </font> <?}else{?> <font class="form_element"> <font color="#dd0000">*</font>&nbsp;Upload Software File: <?}?> </div> </B> </td> <td class="font1" bgcolor="White" align="center" style="padding-left:2px;"><input type="file" name="frm_image[]" class="text_area"> </td> <?if($frm_sfile !=""){?> <td class="font1" bgcolor="White" align="center"></td> <?}else{?> <td class="font1" bgcolor="White" align="center">&nbsp;(Current File: NOT Uploaded Yet) </td> <?}?> </tr> </table></td> </tr> <tr> <td colspan="2"> <div id="dynamicInput"> </div> </td> </tr> <? if(isset($_REQUEST['edit'])){?> <tr> <td colspan="2"><table border="0" cellpadding="0" cellspacing="0"> <tr align="center" valign="middle" class="tbl_row1"> <td height="25" align="left" class="font1" width="156" bgcolor="White"><div align="right">&nbsp;Upload Version TXT File: </div> </B> </td> <td class="font1" bgcolor="White" align="right" style="padding-left:2px;"><input type="file" name="frm_version_txt" class="text_area"> </td> <?if($frm_vers_txt !=""){?> <td class="font1" bgcolor="White" align="center">&nbsp;(Current File: <?echo $frm_vers_txt;?>) </td> <?}else{?> <td class="font1" bgcolor="White" align="center">&nbsp;(Current File: NOT Uploaded Yet) </td> <?}?> </tr> </table></td> </tr> <?}?> <tr><td colspan="2" height="5" ></td></tr> <tr> <td align="right" width="30%" style="font-size:13px;color:#000000;" colspan="2"><div align="left"><font color="#dd0000">&nbsp;&nbsp;&nbsp;*</font> Asterisks denote required fields&nbsp;&nbsp;</div></td> </tr> <tr><td colspan="2" height="5" ></td></tr> <tr> <td align="right" width="30%" style="font-size:13px;color:#000000;" colspan="2"><div align="left"><font color="#dd0000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font>Note: Only one software can be uploaded per Operating System for a particular version. </div></td> </tr> <tr> <td colspan="2" height="5" ></td> </tr> <tr valign="middle" bgcolor="White"> <td nowrap colspan="2"><div align="center"> <table> <tr> <input type="hidden" name="like" value="<?=$sub_like?>"> <input type="hidden" name="offset" value="<?=$offset?>"> <input type="hidden" name="edit" value="<?=$faq_id?>"> <input type="hidden" name="add" value="<?=$_REQUEST[add]?>"> <input type="hidden" name="ex_np_link" value="<?=$ex_np_link?>"> <input type="hidden" name="frm_group_show" value="<?=$frm_bc?>"> <input type="hidden" name="frm_pd_id" value="<?=$pdct_id?>"> <input type="hidden" name="count_val" value="1" id="id_count"> <!-- <input type="hidden" name="frm_pdct" value="<?=$pdct_id?>"> <input type="hidden" name="frm_dname" value="<?=$frm_question?>"> <input type="hidden" name="frm_date_created" value="<?=$edit_created_date?>"> --> <input type="hidden" name="frm_txt_else" value="<?=$frm_vers_txt?>"> </tr> </table> </div> </td> </tr> </table> </div> </td> <th background="../admin_images/bg4.jpg" style="background-repeat:repeat-y "scope="row"></th> </tr> <tr> <th width="3%" background="../admin_images/bg8.jpg" style="background-repeat:repeat-y "scope="row">&nbsp;</th> <td colspan="2" style="padding-left:5px;padding-bottom:1px;"><table width="100%" border="0" cellspacing="0" cellpadding="0"> <tr> <td colspan="2" valign="top"><div align="right"> <table border="0"> <tr> <td vAlign="right" title="Save">&nbsp; <input type="Image" src="./../admin_images/save.jpg" name="btn_submit" value="<?=$btn_value?>" onClick="return validate(this.form);"> </td> <td title="Cancel"><a href="manage-software.php?field_name=SUnq&sort_meth=<?=$sort_meth?>&like=<?=$sub_like?>&offset=<?=$offset?>&frm_group_show=<?=$frm_bc?>"><img src="./../admin_images/cancel.jpg" border="0" align="absmiddle"></a></td> <input type="hidden" name="like" value="<?=$sub_like?>"> <input type="hidden" name="offset" value="<?=$offset?>"> </tr> </table> </div></td> </tr> </table></td> <th background="../admin_images/bg4.jpg" style="background-repeat:repeat-y "scope="row"></th> </tr> </form> For the simplicity of viewing this code page i have included only required code lines please help me to solve this issue

    Read the article

  • Hosting the Razor Engine for Templating in Non-Web Applications

    - by Rick Strahl
    Microsoft’s new Razor HTML Rendering Engine that is currently shipping with ASP.NET MVC previews can be used outside of ASP.NET. Razor is an alternative view engine that can be used instead of the ASP.NET Page engine that currently works with ASP.NET WebForms and MVC. It provides a simpler and more readable markup syntax and is much more light weight in terms of functionality than the full blown WebForms Page engine, focusing only on features that are more along the lines of a pure view engine (or classic ASP!) with focus on expression and code rendering rather than a complex control/object model. Like the Page engine though, the parser understands .NET code syntax which can be embedded into templates, and behind the scenes the engine compiles markup and script code into an executing piece of .NET code in an assembly. Although it ships as part of the ASP.NET MVC and WebMatrix the Razor Engine itself is not directly dependent on ASP.NET or IIS or HTTP in any way. And although there are some markup and rendering features that are optimized for HTML based output generation, Razor is essentially a free standing template engine. And what’s really nice is that unlike the ASP.NET Runtime, Razor is fairly easy to host inside of your own non-Web applications to provide templating functionality. Templating in non-Web Applications? Yes please! So why might you host a template engine in your non-Web application? Template rendering is useful in many places and I have a number of applications that make heavy use of it. One of my applications – West Wind Html Help Builder - exclusively uses template based rendering to merge user supplied help text content into customizable and executable HTML markup templates that provide HTML output for CHM style HTML Help. This is an older product and it’s not actually using .NET at the moment – and this is one reason I’m looking at Razor for script hosting at the moment. For a few .NET applications though I’ve actually used the ASP.NET Runtime hosting to provide templating and mail merge style functionality and while that works reasonably well it’s a very heavy handed approach. It’s very resource intensive and has potential issues with versioning in various different versions of .NET. The generic implementation I created in the article above requires a lot of fix up to mimic an HTTP request in a non-HTTP environment and there are a lot of little things that have to happen to ensure that the ASP.NET runtime works properly most of it having nothing to do with the templating aspect but just satisfying ASP.NET’s requirements. The Razor Engine on the other hand is fairly light weight and completely decoupled from the ASP.NET runtime and the HTTP processing. Rather it’s a pure template engine whose sole purpose is to render text templates. Hosting this engine in your own applications can be accomplished with a reasonable amount of code (actually just a few lines with the tools I’m about to describe) and without having to fake HTTP requests. It’s also much lighter on resource usage and you can easily attach custom properties to your base template implementation to easily pass context from the parent application into templates all of which was rather complicated with ASP.NET runtime hosting. Installing the Razor Template Engine You can get Razor as part of the MVC 3 (RC and later) or Web Matrix. Both are available as downloadable components from the Web Platform Installer Version 3.0 (!important – V2 doesn’t show these components). If you already have that version of the WPI installed just fire it up. You can get the latest version of the Web Platform Installer from here: http://www.microsoft.com/web/gallery/install.aspx Once the platform Installer 3.0 is installed install either MVC 3 or ASP.NET Web Pages. Once installed you’ll find a System.Web.Razor assembly in C:\Program Files\Microsoft ASP.NET\ASP.NET Web Pages\v1.0\Assemblies\System.Web.Razor.dll which you can add as a reference to your project. Creating a Wrapper The basic Razor Hosting API is pretty simple and you can host Razor with a (large-ish) handful of lines of code. I’ll show the basics of it later in this article. However, if you want to customize the rendering and handle assembly and namespace includes for the markup as well as deal with text and file inputs as well as forcing Razor to run in a separate AppDomain so you can unload the code-generated assemblies and deal with assembly caching for re-used templates little more work is required to create something that is more easily reusable. For this reason I created a Razor Hosting wrapper project that combines a bunch of this functionality into an easy to use hosting class, a hosting factory that can load the engine in a separate AppDomain and a couple of hosting containers that provided folder based and string based caching for templates for an easily embeddable and reusable engine with easy to use syntax. If you just want the code and play with the samples and source go grab the latest code from the Subversion Repository at: http://www.west-wind.com:8080/svn/articles/trunk/RazorHosting/ or a snapshot from: http://www.west-wind.com/files/tools/RazorHosting.zip Getting Started Before I get into how hosting with Razor works, let’s take a look at how you can get up and running quickly with the wrapper classes provided. It only takes a few lines of code. The easiest way to use these Razor Hosting Wrappers is to use one of the two HostContainers provided. One is for hosting Razor scripts in a directory and rendering them as relative paths from these script files on disk. The other HostContainer serves razor scripts from string templates… Let’s start with a very simple template that displays some simple expressions, some code blocks and demonstrates rendering some data from contextual data that you pass to the template in the form of a ‘context’. Here’s a simple Razor template: @using System.Reflection Hello @Context.FirstName! Your entry was entered on: @Context.Entered @{ // Code block: Update the host Windows Form passed in through the context Context.WinForm.Text = "Hello World from Razor at " + DateTime.Now.ToString(); } AppDomain Id: @AppDomain.CurrentDomain.FriendlyName Assembly: @Assembly.GetExecutingAssembly().FullName Code based output: @{ // Write output with Response object from code string output = string.Empty; for (int i = 0; i < 10; i++) { output += i.ToString() + " "; } Response.Write(output); } Pretty easy to see what’s going on here. The only unusual thing in this code is the Context object which is an arbitrary object I’m passing from the host to the template by way of the template base class. I’m also displaying the current AppDomain and the executing Assembly name so you can see how compiling and running a template actually loads up new assemblies. Also note that as part of my context I’m passing a reference to the current Windows Form down to the template and changing the title from within the script. It’s a silly example, but it demonstrates two-way communication between host and template and back which can be very powerful. The easiest way to quickly render this template is to use the RazorEngine<TTemplateBase> class. The generic parameter specifies a template base class type that is used by Razor internally to generate the class it generates from a template. The default implementation provided in my RazorHosting wrapper is RazorTemplateBase. Here’s a simple one that renders from a string and outputs a string: var engine = new RazorEngine<RazorTemplateBase>(); // we can pass any object as context - here create a custom context var context = new CustomContext() { WinForm = this, FirstName = "Rick", Entered = DateTime.Now.AddDays(-10) }; string output = engine.RenderTemplate(this.txtSource.Text new string[] { "System.Windows.Forms.dll" }, context); if (output == null) this.txtResult.Text = "*** ERROR:\r\n" + engine.ErrorMessage; else this.txtResult.Text = output; Simple enough. This code renders a template from a string input and returns a result back as a string. It  creates a custom context and passes that to the template which can then access the Context’s properties. Note that anything passed as ‘context’ must be serializable (or MarshalByRefObject) – otherwise you get an exception when passing the reference over AppDomain boundaries (discussed later). Passing a context is optional, but is a key feature in being able to share data between the host application and the template. Note that we use the Context object to access FirstName, Entered and even the host Windows Form object which is used in the template to change the Window caption from within the script! In the code above all the work happens in the RenderTemplate method which provide a variety of overloads to read and write to and from strings, files and TextReaders/Writers. Here’s another example that renders from a file input using a TextReader: using (reader = new StreamReader("templates\\simple.csHtml", true)) { result = host.RenderTemplate(reader, new string[] { "System.Windows.Forms.dll" }, this.CustomContext); } RenderTemplate() is fairly high level and it handles loading of the runtime, compiling into an assembly and rendering of the template. If you want more control you can use the lower level methods to control each step of the way which is important for the HostContainers I’ll discuss later. Basically for those scenarios you want to separate out loading of the engine, compiling into an assembly and then rendering the template from the assembly. Why? So we can keep assemblies cached. In the code above a new assembly is created for each template rendered which is inefficient and uses up resources. Depending on the size of your templates and how often you fire them you can chew through memory very quickly. This slighter lower level approach is only a couple of extra steps: // we can pass any object as context - here create a custom context var context = new CustomContext() { WinForm = this, FirstName = "Rick", Entered = DateTime.Now.AddDays(-10) }; var engine = new RazorEngine<RazorTemplateBase>(); string assId = null; using (StringReader reader = new StringReader(this.txtSource.Text)) { assId = engine.ParseAndCompileTemplate(new string[] { "System.Windows.Forms.dll" }, reader); } string output = engine.RenderTemplateFromAssembly(assId, context); if (output == null) this.txtResult.Text = "*** ERROR:\r\n" + engine.ErrorMessage; else this.txtResult.Text = output; The difference here is that you can capture the assembly – or rather an Id to it – and potentially hold on to it to render again later assuming the template hasn’t changed. The HostContainers take advantage of this feature to cache the assemblies based on certain criteria like a filename and file time step or a string hash that if not change indicate that an assembly can be reused. Note that ParseAndCompileTemplate returns an assembly Id rather than the assembly itself. This is done so that that the assembly always stays in the host’s AppDomain and is not passed across AppDomain boundaries which would cause load failures. We’ll talk more about this in a minute but for now just realize that assemblies references are stored in a list and are accessible by this ID to allow locating and re-executing of the assembly based on that id. Reuse of the assembly avoids recompilation overhead and creation of yet another assembly that loads into the current AppDomain. You can play around with several different versions of the above code in the main sample form:   Using Hosting Containers for more Control and Caching The above examples simply render templates into assemblies each and every time they are executed. While this works and is even reasonably fast, it’s not terribly efficient. If you render templates more than once it would be nice if you could cache the generated assemblies for example to avoid re-compiling and creating of a new assembly each time. Additionally it would be nice to load template assemblies into a separate AppDomain optionally to be able to be able to unload assembli es and also to protect your host application from scripting attacks with malicious template code. Hosting containers provide also provide a wrapper around the RazorEngine<T> instance, a factory (which allows creation in separate AppDomains) and an easy way to start and stop the container ‘runtime’. The Razor Hosting samples provide two hosting containers: RazorFolderHostContainer and StringHostContainer. The folder host provides a simple runtime environment for a folder structure similar in the way that the ASP.NET runtime handles a virtual directory as it’s ‘application' root. Templates are loaded from disk in relative paths and the resulting assemblies are cached unless the template on disk is changed. The string host also caches templates based on string hashes – if the same string is passed a second time a cached version of the assembly is used. Here’s how HostContainers work. I’ll use the FolderHostContainer because it’s likely the most common way you’d use templates – from disk based templates that can be easily edited and maintained on disk. The first step is to create an instance of it and keep it around somewhere (in the example it’s attached as a property to the Form): RazorFolderHostContainer Host = new RazorFolderHostContainer(); public RazorFolderHostForm() { InitializeComponent(); // The base path for templates - templates are rendered with relative paths // based on this path. Host.TemplatePath = Path.Combine(Environment.CurrentDirectory, TemplateBaseFolder); // Add any assemblies you want reference in your templates Host.ReferencedAssemblies.Add("System.Windows.Forms.dll"); // Start up the host container Host.Start(); } Next anytime you want to render a template you can use simple code like this: private void RenderTemplate(string fileName) { // Pass the template path via the Context var relativePath = Utilities.GetRelativePath(fileName, Host.TemplatePath); if (!Host.RenderTemplate(relativePath, this.Context, Host.RenderingOutputFile)) { MessageBox.Show("Error: " + Host.ErrorMessage); return; } this.webBrowser1.Navigate("file://" + Host.RenderingOutputFile); } You can also render the output to a string instead of to a file: string result = Host.RenderTemplateToString(relativePath,context); Finally if you want to release the engine and shut down the hosting AppDomain you can simply do: Host.Stop(); Stopping the AppDomain and restarting it (ie. calling Stop(); followed by Start()) is also a nice way to release all resources in the AppDomain. The FolderBased domain also supports partial Rendering based on root path based relative paths with the same caching characteristics as the main templates. From within a template you can call out to a partial like this: @RenderPartial(@"partials\PartialRendering.cshtml", Context) where partials\PartialRendering.cshtml is a relative to the template root folder. The folder host example lets you load up templates from disk and display the result in a Web Browser control which demonstrates using Razor HTML output from templates that contain HTML syntax which happens to me my target scenario for Html Help Builder.   The Razor Engine Wrapper Project The project I created to wrap Razor hosting has a fair bit of code and a number of classes associated with it. Most of the components are internally used and as you can see using the final RazorEngine<T> and HostContainer classes is pretty easy. The classes are extensible and I suspect developers will want to build more customized host containers for their applications. Host containers are the key to wrapping up all functionality – Engine, BaseTemplate, AppDomain Hosting, Caching etc in a logical piece that is ready to be plugged into an application. When looking at the code there are a couple of core features provided: Core Razor Engine Hosting This is the core Razor hosting which provides the basics of loading a template, compiling it into an assembly and executing it. This is fairly straightforward, but without a host container that can cache assemblies based on some criteria templates are recompiled and re-created each time which is inefficient (although pretty fast). The base engine wrapper implementation also supports hosting the Razor runtime in a separate AppDomain for security and the ability to unload it on demand. Host Containers The engine hosting itself doesn’t provide any sort of ‘runtime’ service like picking up files from disk, caching assemblies and so forth. So my implementation provides two HostContainers: RazorFolderHostContainer and RazorStringHostContainer. The FolderHost works off a base directory and loads templates based on relative paths (sort of like the ASP.NET runtime does off a virtual). The HostContainers also deal with caching of template assemblies – for the folder host the file date is tracked and checked for updates and unless the template is changed a cached assembly is reused. The StringHostContainer similiarily checks string hashes to figure out whether a particular string template was previously compiled and executed. The HostContainers also act as a simple startup environment and a single reference to easily store and reuse in an application. TemplateBase Classes The template base classes are the base classes that from which the Razor engine generates .NET code. A template is parsed into a class with an Execute() method and the class is based on this template type you can specify. RazorEngine<TBaseTemplate> can receive this type and the HostContainers default to specific templates in their base implementations. Template classes are customizable to allow you to create templates that provide application specific features and interaction from the template to your host application. How does the RazorEngine wrapper work? You can browse the source code in the links above or in the repository or download the source, but I’ll highlight some key features here. Here’s part of the RazorEngine implementation that can be used to host the runtime and that demonstrates the key code required to host the Razor runtime. The RazorEngine class is implemented as a generic class to reflect the Template base class type: public class RazorEngine<TBaseTemplateType> : MarshalByRefObject where TBaseTemplateType : RazorTemplateBase The generic type is used to internally provide easier access to the template type and assignments on it as part of the template processing. The class also inherits MarshalByRefObject to allow execution over AppDomain boundaries – something that all the classes discussed here need to do since there is much interaction between the host and the template. The first two key methods deal with creating a template assembly: /// <summary> /// Creates an instance of the RazorHost with various options applied. /// Applies basic namespace imports and the name of the class to generate /// </summary> /// <param name="generatedNamespace"></param> /// <param name="generatedClass"></param> /// <returns></returns> protected RazorTemplateEngine CreateHost(string generatedNamespace, string generatedClass) { Type baseClassType = typeof(TBaseTemplateType); RazorEngineHost host = new RazorEngineHost(new CSharpRazorCodeLanguage()); host.DefaultBaseClass = baseClassType.FullName; host.DefaultClassName = generatedClass; host.DefaultNamespace = generatedNamespace; host.NamespaceImports.Add("System"); host.NamespaceImports.Add("System.Text"); host.NamespaceImports.Add("System.Collections.Generic"); host.NamespaceImports.Add("System.Linq"); host.NamespaceImports.Add("System.IO"); return new RazorTemplateEngine(host); } /// <summary> /// Parses and compiles a markup template into an assembly and returns /// an assembly name. The name is an ID that can be passed to /// ExecuteTemplateByAssembly which picks up a cached instance of the /// loaded assembly. /// /// </summary> /// <param name="namespaceOfGeneratedClass">The namespace of the class to generate from the template</param> /// <param name="generatedClassName">The name of the class to generate from the template</param> /// <param name="ReferencedAssemblies">Any referenced assemblies by dll name only. Assemblies must be in execution path of host or in GAC.</param> /// <param name="templateSourceReader">Textreader that loads the template</param> /// <remarks> /// The actual assembly isn't returned here to allow for cross-AppDomain /// operation. If the assembly was returned it would fail for cross-AppDomain /// calls. /// </remarks> /// <returns>An assembly Id. The Assembly is cached in memory and can be used with RenderFromAssembly.</returns> public string ParseAndCompileTemplate( string namespaceOfGeneratedClass, string generatedClassName, string[] ReferencedAssemblies, TextReader templateSourceReader) { RazorTemplateEngine engine = CreateHost(namespaceOfGeneratedClass, generatedClassName); // Generate the template class as CodeDom GeneratorResults razorResults = engine.GenerateCode(templateSourceReader); // Create code from the codeDom and compile CSharpCodeProvider codeProvider = new CSharpCodeProvider(); CodeGeneratorOptions options = new CodeGeneratorOptions(); // Capture Code Generated as a string for error info // and debugging LastGeneratedCode = null; using (StringWriter writer = new StringWriter()) { codeProvider.GenerateCodeFromCompileUnit(razorResults.GeneratedCode, writer, options); LastGeneratedCode = writer.ToString(); } CompilerParameters compilerParameters = new CompilerParameters(ReferencedAssemblies); // Standard Assembly References compilerParameters.ReferencedAssemblies.Add("System.dll"); compilerParameters.ReferencedAssemblies.Add("System.Core.dll"); compilerParameters.ReferencedAssemblies.Add("Microsoft.CSharp.dll"); // dynamic support! // Also add the current assembly so RazorTemplateBase is available compilerParameters.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().CodeBase.Substring(8)); compilerParameters.GenerateInMemory = Configuration.CompileToMemory; if (!Configuration.CompileToMemory) compilerParameters.OutputAssembly = Path.Combine(Configuration.TempAssemblyPath, "_" + Guid.NewGuid().ToString("n") + ".dll"); CompilerResults compilerResults = codeProvider.CompileAssemblyFromDom(compilerParameters, razorResults.GeneratedCode); if (compilerResults.Errors.Count > 0) { var compileErrors = new StringBuilder(); foreach (System.CodeDom.Compiler.CompilerError compileError in compilerResults.Errors) compileErrors.Append(String.Format(Resources.LineX0TColX1TErrorX2RN, compileError.Line, compileError.Column, compileError.ErrorText)); this.SetError(compileErrors.ToString() + "\r\n" + LastGeneratedCode); return null; } AssemblyCache.Add(compilerResults.CompiledAssembly.FullName, compilerResults.CompiledAssembly); return compilerResults.CompiledAssembly.FullName; } Think of the internal CreateHost() method as setting up the assembly generated from each template. Each template compiles into a separate assembly. It sets up namespaces, and assembly references, the base class used and the name and namespace for the generated class. ParseAndCompileTemplate() then calls the CreateHost() method to receive the template engine generator which effectively generates a CodeDom from the template – the template is turned into .NET code. The code generated from our earlier example looks something like this: //------------------------------------------------------------------------------ // <auto-generated> // This code was generated by a tool. // Runtime Version:4.0.30319.1 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // </auto-generated> //------------------------------------------------------------------------------ namespace RazorTest { using System; using System.Text; using System.Collections.Generic; using System.Linq; using System.IO; using System.Reflection; public class RazorTemplate : RazorHosting.RazorTemplateBase { #line hidden public RazorTemplate() { } public override void Execute() { WriteLiteral("Hello "); Write(Context.FirstName); WriteLiteral("! Your entry was entered on: "); Write(Context.Entered); WriteLiteral("\r\n\r\n"); // Code block: Update the host Windows Form passed in through the context Context.WinForm.Text = "Hello World from Razor at " + DateTime.Now.ToString(); WriteLiteral("\r\nAppDomain Id:\r\n "); Write(AppDomain.CurrentDomain.FriendlyName); WriteLiteral("\r\n \r\nAssembly:\r\n "); Write(Assembly.GetExecutingAssembly().FullName); WriteLiteral("\r\n\r\nCode based output: \r\n"); // Write output with Response object from code string output = string.Empty; for (int i = 0; i < 10; i++) { output += i.ToString() + " "; } } } } Basically the template’s body is turned into code in an Execute method that is called. Internally the template’s Write method is fired to actually generate the output. Note that the class inherits from RazorTemplateBase which is the generic parameter I used to specify the base class when creating an instance in my RazorEngine host: var engine = new RazorEngine<RazorTemplateBase>(); This template class must be provided and it must implement an Execute() and Write() method. Beyond that you can create any class you chose and attach your own properties. My RazorTemplateBase class implementation is very simple: public class RazorTemplateBase : MarshalByRefObject, IDisposable { /// <summary> /// You can pass in a generic context object /// to use in your template code /// </summary> public dynamic Context { get; set; } /// <summary> /// Class that generates output. Currently ultra simple /// with only Response.Write() implementation. /// </summary> public RazorResponse Response { get; set; } public object HostContainer {get; set; } public object Engine { get; set; } public RazorTemplateBase() { Response = new RazorResponse(); } public virtual void Write(object value) { Response.Write(value); } public virtual void WriteLiteral(object value) { Response.Write(value); } /// <summary> /// Razor Parser implements this method /// </summary> public virtual void Execute() {} public virtual void Dispose() { if (Response != null) { Response.Dispose(); Response = null; } } } Razor fills in the Execute method when it generates its subclass and uses the Write() method to output content. As you can see I use a RazorResponse() class here to generate output. This isn’t necessary really, as you could use a StringBuilder or StringWriter() directly, but I prefer using Response object so I can extend the Response behavior as needed. The RazorResponse class is also very simple and merely acts as a wrapper around a TextWriter: public class RazorResponse : IDisposable { /// <summary> /// Internal text writer - default to StringWriter() /// </summary> public TextWriter Writer = new StringWriter(); public virtual void Write(object value) { Writer.Write(value); } public virtual void WriteLine(object value) { Write(value); Write("\r\n"); } public virtual void WriteFormat(string format, params object[] args) { Write(string.Format(format, args)); } public override string ToString() { return Writer.ToString(); } public virtual void Dispose() { Writer.Close(); } public virtual void SetTextWriter(TextWriter writer) { // Close original writer if (Writer != null) Writer.Close(); Writer = writer; } } The Rendering Methods of RazorEngine At this point I’ve talked about the assembly generation logic and the template implementation itself. What’s left is that once you’ve generated the assembly is to execute it. The code to do this is handled in the various RenderXXX methods of the RazorEngine class. Let’s look at the lowest level one of these which is RenderTemplateFromAssembly() and a couple of internal support methods that handle instantiating and invoking of the generated template method: public string RenderTemplateFromAssembly( string assemblyId, string generatedNamespace, string generatedClass, object context, TextWriter outputWriter) { this.SetError(); Assembly generatedAssembly = AssemblyCache[assemblyId]; if (generatedAssembly == null) { this.SetError(Resources.PreviouslyCompiledAssemblyNotFound); return null; } string className = generatedNamespace + "." + generatedClass; Type type; try { type = generatedAssembly.GetType(className); } catch (Exception ex) { this.SetError(Resources.UnableToCreateType + className + ": " + ex.Message); return null; } // Start with empty non-error response (if we use a writer) string result = string.Empty; using(TBaseTemplateType instance = InstantiateTemplateClass(type)) { if (instance == null) return null; if (outputWriter != null) instance.Response.SetTextWriter(outputWriter); if (!InvokeTemplateInstance(instance, context)) return null; // Capture string output if implemented and return // otherwise null is returned if (outputWriter == null) result = instance.Response.ToString(); } return result; } protected virtual TBaseTemplateType InstantiateTemplateClass(Type type) { TBaseTemplateType instance = Activator.CreateInstance(type) as TBaseTemplateType; if (instance == null) { SetError(Resources.CouldnTActivateTypeInstance + type.FullName); return null; } instance.Engine = this; // If a HostContainer was set pass that to the template too instance.HostContainer = this.HostContainer; return instance; } /// <summary> /// Internally executes an instance of the template, /// captures errors on execution and returns true or false /// </summary> /// <param name="instance">An instance of the generated template</param> /// <returns>true or false - check ErrorMessage for errors</returns> protected virtual bool InvokeTemplateInstance(TBaseTemplateType instance, object context) { try { instance.Context = context; instance.Execute(); } catch (Exception ex) { this.SetError(Resources.TemplateExecutionError + ex.Message); return false; } finally { // Must make sure Response is closed instance.Response.Dispose(); } return true; } The RenderTemplateFromAssembly method basically requires the namespace and class to instantate and creates an instance of the class using InstantiateTemplateClass(). It then invokes the method with InvokeTemplateInstance(). These two methods are broken out because they are re-used by various other rendering methods and also to allow subclassing and providing additional configuration tasks to set properties and pass values to templates at execution time. In the default mode instantiation sets the Engine and HostContainer (discussed later) so the template can call back into the template engine, and the context is set when the template method is invoked. The various RenderXXX methods use similar code although they create the assemblies first. If you’re after potentially cashing assemblies the method is the one to call and that’s exactly what the two HostContainer classes do. More on that in a minute, but before we get into HostContainers let’s talk about AppDomain hosting and the like. Running Templates in their own AppDomain With the RazorEngine class above, when a template is parsed into an assembly and executed the assembly is created (in memory or on disk – you can configure that) and cached in the current AppDomain. In .NET once an assembly has been loaded it can never be unloaded so if you’re loading lots of templates and at some time you want to release them there’s no way to do so. If however you load the assemblies in a separate AppDomain that new AppDomain can be unloaded and the assemblies loaded in it with it. In order to host the templates in a separate AppDomain the easiest thing to do is to run the entire RazorEngine in a separate AppDomain. Then all interaction occurs in the other AppDomain and no further changes have to be made. To facilitate this there is a RazorEngineFactory which has methods that can instantiate the RazorHost in a separate AppDomain as well as in the local AppDomain. The host creates the remote instance and then hangs on to it to keep it alive as well as providing methods to shut down the AppDomain and reload the engine. Sounds complicated but cross-AppDomain invocation is actually fairly easy to implement. Here’s some of the relevant code from the RazorEngineFactory class. Like the RazorEngine this class is generic and requires a template base type in the generic class name: public class RazorEngineFactory<TBaseTemplateType> where TBaseTemplateType : RazorTemplateBase Here are the key methods of interest: /// <summary> /// Creates an instance of the RazorHost in a new AppDomain. This /// version creates a static singleton that that is cached and you /// can call UnloadRazorHostInAppDomain to unload it. /// </summary> /// <returns></returns> public static RazorEngine<TBaseTemplateType> CreateRazorHostInAppDomain() { if (Current == null) Current = new RazorEngineFactory<TBaseTemplateType>(); return Current.GetRazorHostInAppDomain(); } public static void UnloadRazorHostInAppDomain() { if (Current != null) Current.UnloadHost(); Current = null; } /// <summary> /// Instance method that creates a RazorHost in a new AppDomain. /// This method requires that you keep the Factory around in /// order to keep the AppDomain alive and be able to unload it. /// </summary> /// <returns></returns> public RazorEngine<TBaseTemplateType> GetRazorHostInAppDomain() { LocalAppDomain = CreateAppDomain(null); if (LocalAppDomain == null) return null; /// Create the instance inside of the new AppDomain /// Note: remote domain uses local EXE's AppBasePath!!! RazorEngine<TBaseTemplateType> host = null; try { Assembly ass = Assembly.GetExecutingAssembly(); string AssemblyPath = ass.Location; host = (RazorEngine<TBaseTemplateType>) LocalAppDomain.CreateInstanceFrom(AssemblyPath, typeof(RazorEngine<TBaseTemplateType>).FullName).Unwrap(); } catch (Exception ex) { ErrorMessage = ex.Message; return null; } return host; } /// <summary> /// Internally creates a new AppDomain in which Razor templates can /// be run. /// </summary> /// <param name="appDomainName"></param> /// <returns></returns> private AppDomain CreateAppDomain(string appDomainName) { if (appDomainName == null) appDomainName = "RazorHost_" + Guid.NewGuid().ToString("n"); AppDomainSetup setup = new AppDomainSetup(); // *** Point at current directory setup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory; AppDomain localDomain = AppDomain.CreateDomain(appDomainName, null, setup); return localDomain; } /// <summary> /// Allow unloading of the created AppDomain to release resources /// All internal resources in the AppDomain are released including /// in memory compiled Razor assemblies. /// </summary> public void UnloadHost() { if (this.LocalAppDomain != null) { AppDomain.Unload(this.LocalAppDomain); this.LocalAppDomain = null; } } The static CreateRazorHostInAppDomain() is the key method that startup code usually calls. It uses a Current singleton instance to an instance of itself that is created cross AppDomain and is kept alive because it’s static. GetRazorHostInAppDomain actually creates a cross-AppDomain instance which first creates a new AppDomain and then loads the RazorEngine into it. The remote Proxy instance is returned as a result to the method and can be used the same as a local instance. The code to run with a remote AppDomain is simple: private RazorEngine<RazorTemplateBase> CreateHost() { if (this.Host != null) return this.Host; // Use Static Methods - no error message if host doesn't load this.Host = RazorEngineFactory<RazorTemplateBase>.CreateRazorHostInAppDomain(); if (this.Host == null) { MessageBox.Show("Unable to load Razor Template Host", "Razor Hosting", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } return this.Host; } This code relies on a local reference of the Host which is kept around for the duration of the app (in this case a form reference). To use this you’d simply do: this.Host = CreateHost(); if (host == null) return; string result = host.RenderTemplate( this.txtSource.Text, new string[] { "System.Windows.Forms.dll", "Westwind.Utilities.dll" }, this.CustomContext); if (result == null) { MessageBox.Show(host.ErrorMessage, "Template Execution Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } this.txtResult.Text = result; Now all templates run in a remote AppDomain and can be unloaded with simple code like this: RazorEngineFactory<RazorTemplateBase>.UnloadRazorHostInAppDomain(); this.Host = null; One Step further – Providing a caching ‘Runtime’ Once we can load templates in a remote AppDomain we can add some additional functionality like assembly caching based on application specific features. One of my typical scenarios is to render templates out of a scripts folder. So all templates live in a folder and they change infrequently. So a Folder based host that can compile these templates once and then only recompile them if something changes would be ideal. Enter host containers which are basically wrappers around the RazorEngine<t> and RazorEngineFactory<t>. They provide additional logic for things like file caching based on changes on disk or string hashes for string based template inputs. The folder host also provides for partial rendering logic through a custom template base implementation. There’s a base implementation in RazorBaseHostContainer, which provides the basics for hosting a RazorEngine, which includes the ability to start and stop the engine, cache assemblies and add references: public abstract class RazorBaseHostContainer<TBaseTemplateType> : MarshalByRefObject where TBaseTemplateType : RazorTemplateBase, new() { public RazorBaseHostContainer() { UseAppDomain = true; GeneratedNamespace = "__RazorHost"; } /// <summary> /// Determines whether the Container hosts Razor /// in a separate AppDomain. Seperate AppDomain /// hosting allows unloading and releasing of /// resources. /// </summary> public bool UseAppDomain { get; set; } /// <summary> /// Base folder location where the AppDomain /// is hosted. By default uses the same folder /// as the host application. /// /// Determines where binary dependencies are /// found for assembly references. /// </summary> public string BaseBinaryFolder { get; set; } /// <summary> /// List of referenced assemblies as string values. /// Must be in GAC or in the current folder of the host app/ /// base BinaryFolder /// </summary> public List<string> ReferencedAssemblies = new List<string>(); /// <summary> /// Name of the generated namespace for template classes /// </summary> public string GeneratedNamespace {get; set; } /// <summary> /// Any error messages /// </summary> public string ErrorMessage { get; set; } /// <summary> /// Cached instance of the Host. Required to keep the /// reference to the host alive for multiple uses. /// </summary> public RazorEngine<TBaseTemplateType> Engine; /// <summary> /// Cached instance of the Host Factory - so we can unload /// the host and its associated AppDomain. /// </summary> protected RazorEngineFactory<TBaseTemplateType> EngineFactory; /// <summary> /// Keep track of each compiled assembly /// and when it was compiled. /// /// Use a hash of the string to identify string /// changes. /// </summary> protected Dictionary<int, CompiledAssemblyItem> LoadedAssemblies = new Dictionary<int, CompiledAssemblyItem>(); /// <summary> /// Call to start the Host running. Follow by a calls to RenderTemplate to /// render individual templates. Call Stop when done. /// </summary> /// <returns>true or false - check ErrorMessage on false </returns> public virtual bool Start() { if (Engine == null) { if (UseAppDomain) Engine = RazorEngineFactory<TBaseTemplateType>.CreateRazorHostInAppDomain(); else Engine = RazorEngineFactory<TBaseTemplateType>.CreateRazorHost(); Engine.Configuration.CompileToMemory = true; Engine.HostContainer = this; if (Engine == null) { this.ErrorMessage = EngineFactory.ErrorMessage; return false; } } return true; } /// <summary> /// Stops the Host and releases the host AppDomain and cached /// assemblies. /// </summary> /// <returns>true or false</returns> public bool Stop() { this.LoadedAssemblies.Clear(); RazorEngineFactory<RazorTemplateBase>.UnloadRazorHostInAppDomain(); this.Engine = null; return true; } … } This base class provides most of the mechanics to host the runtime, but no application specific implementation for rendering. There are rendering functions but they just call the engine directly and provide no caching – there’s no context to decide how to cache and reuse templates. The key methods are Start and Stop and their main purpose is to start a new AppDomain (optionally) and shut it down when requested. The RazorFolderHostContainer – Folder Based Runtime Hosting Let’s look at the more application specific RazorFolderHostContainer implementation which is defined like this: public class RazorFolderHostContainer : RazorBaseHostContainer<RazorTemplateFolderHost> Note that a customized RazorTemplateFolderHost class template is used for this implementation that supports partial rendering in form of a RenderPartial() method that’s available to templates. The folder host’s features are: Render templates based on a Template Base Path (a ‘virtual’ if you will) Cache compiled assemblies based on the relative path and file time stamp File changes on templates cause templates to be recompiled into new assemblies Support for partial rendering using base folder relative pathing As shown in the startup examples earlier host containers require some startup code with a HostContainer tied to a persistent property (like a Form property): // The base path for templates - templates are rendered with relative paths // based on this path. HostContainer.TemplatePath = Path.Combine(Environment.CurrentDirectory, TemplateBaseFolder); // Default output rendering disk location HostContainer.RenderingOutputFile = Path.Combine(HostContainer.TemplatePath, "__Preview.htm"); // Add any assemblies you want reference in your templates HostContainer.ReferencedAssemblies.Add("System.Windows.Forms.dll"); // Start up the host container HostContainer.Start(); Once that’s done, you can render templates with the host container: // Pass the template path for full filename seleted with OpenFile Dialog // relativepath is: subdir\file.cshtml or file.cshtml or ..\file.cshtml var relativePath = Utilities.GetRelativePath(fileName, HostContainer.TemplatePath); if (!HostContainer.RenderTemplate(relativePath, Context, HostContainer.RenderingOutputFile)) { MessageBox.Show("Error: " + HostContainer.ErrorMessage); return; } webBrowser1.Navigate("file://" + HostContainer.RenderingOutputFile); The most critical task of the RazorFolderHostContainer implementation is to retrieve a template from disk, compile and cache it and then deal with deciding whether subsequent requests need to re-compile the template or simply use a cached version. Internally the GetAssemblyFromFileAndCache() handles this task: /// <summary> /// Internally checks if a cached assembly exists and if it does uses it /// else creates and compiles one. Returns an assembly Id to be /// used with the LoadedAssembly list. /// </summary> /// <param name="relativePath"></param> /// <param name="context"></param> /// <returns></returns> protected virtual CompiledAssemblyItem GetAssemblyFromFileAndCache(string relativePath) { string fileName = Path.Combine(TemplatePath, relativePath).ToLower(); int fileNameHash = fileName.GetHashCode(); if (!File.Exists(fileName)) { this.SetError(Resources.TemplateFileDoesnTExist + fileName); return null; } CompiledAssemblyItem item = null; this.LoadedAssemblies.TryGetValue(fileNameHash, out item); string assemblyId = null; // Check for cached instance if (item != null) { var fileTime = File.GetLastWriteTimeUtc(fileName); if (fileTime <= item.CompileTimeUtc) assemblyId = item.AssemblyId; } else item = new CompiledAssemblyItem(); // No cached instance - create assembly and cache if (assemblyId == null) { string safeClassName = GetSafeClassName(fileName); StreamReader reader = null; try { reader = new StreamReader(fileName, true); } catch (Exception ex) { this.SetError(Resources.ErrorReadingTemplateFile + fileName); return null; } assemblyId = Engine.ParseAndCompileTemplate(this.ReferencedAssemblies.ToArray(), reader); // need to ensure reader is closed if (reader != null) reader.Close(); if (assemblyId == null) { this.SetError(Engine.ErrorMessage); return null; } item.AssemblyId = assemblyId; item.CompileTimeUtc = DateTime.UtcNow; item.FileName = fileName; item.SafeClassName = safeClassName; this.LoadedAssemblies[fileNameHash] = item; } return item; } This code uses a LoadedAssembly dictionary which is comprised of a structure that holds a reference to a compiled assembly, a full filename and file timestamp and an assembly id. LoadedAssemblies (defined on the base class shown earlier) is essentially a cache for compiled assemblies and they are identified by a hash id. In the case of files the hash is a GetHashCode() from the full filename of the template. The template is checked for in the cache and if not found the file stamp is checked. If that’s newer than the cache’s compilation date the template is recompiled otherwise the version in the cache is used. All the core work defers to a RazorEngine<T> instance to ParseAndCompileTemplate(). The three rendering specific methods then are rather simple implementations with just a few lines of code dealing with parameter and return value parsing: /// <summary> /// Renders a template to a TextWriter. Useful to write output into a stream or /// the Response object. Used for partial rendering. /// </summary> /// <param name="relativePath">Relative path to the file in the folder structure</param> /// <param name="context">Optional context object or null</param> /// <param name="writer">The textwriter to write output into</param> /// <returns></returns> public bool RenderTemplate(string relativePath, object context, TextWriter writer) { // Set configuration data that is to be passed to the template (any object) Engine.TemplatePerRequestConfigurationData = new RazorFolderHostTemplateConfiguration() { TemplatePath = Path.Combine(this.TemplatePath, relativePath), TemplateRelativePath = relativePath, }; CompiledAssemblyItem item = GetAssemblyFromFileAndCache(relativePath); if (item == null) { writer.Close(); return false; } try { // String result will be empty as output will be rendered into the // Response object's stream output. However a null result denotes // an error string result = Engine.RenderTemplateFromAssembly(item.AssemblyId, context, writer); if (result == null) { this.SetError(Engine.ErrorMessage); return false; } } catch (Exception ex) { this.SetError(ex.Message); return false; } finally { writer.Close(); } return true; } /// <summary> /// Render a template from a source file on disk to a specified outputfile. /// </summary> /// <param name="relativePath">Relative path off the template root folder. Format: path/filename.cshtml</param> /// <param name="context">Any object that will be available in the template as a dynamic of this.Context</param> /// <param name="outputFile">Optional - output file where output is written to. If not specified the /// RenderingOutputFile property is used instead /// </param> /// <returns>true if rendering succeeds, false on failure - check ErrorMessage</returns> public bool RenderTemplate(string relativePath, object context, string outputFile) { if (outputFile == null) outputFile = RenderingOutputFile; try { using (StreamWriter writer = new StreamWriter(outputFile, false, Engine.Configuration.OutputEncoding, Engine.Configuration.StreamBufferSize)) { return RenderTemplate(relativePath, context, writer); } } catch (Exception ex) { this.SetError(ex.Message); return false; } return true; } /// <summary> /// Renders a template to string. Useful for RenderTemplate /// </summary> /// <param name="relativePath"></param> /// <param name="context"></param> /// <returns></returns> public string RenderTemplateToString(string relativePath, object context) { string result = string.Empty; try { using (StringWriter writer = new StringWriter()) { // String result will be empty as output will be rendered into the // Response object's stream output. However a null result denotes // an error if (!RenderTemplate(relativePath, context, writer)) { this.SetError(Engine.ErrorMessage); return null; } result = writer.ToString(); } } catch (Exception ex) { this.SetError(ex.Message); return null; } return result; } The idea is that you can create custom host container implementations that do exactly what you want fairly easily. Take a look at both the RazorFolderHostContainer and RazorStringHostContainer classes for the basic concepts you can use to create custom implementations. Notice also that you can set the engine’s PerRequestConfigurationData() from the host container: // Set configuration data that is to be passed to the template (any object) Engine.TemplatePerRequestConfigurationData = new RazorFolderHostTemplateConfiguration() { TemplatePath = Path.Combine(this.TemplatePath, relativePath), TemplateRelativePath = relativePath, }; which when set to a non-null value is passed to the Template’s InitializeTemplate() method. This method receives an object parameter which you can cast as needed: public override void InitializeTemplate(object configurationData) { // Pick up configuration data and stuff into Request object RazorFolderHostTemplateConfiguration config = configurationData as RazorFolderHostTemplateConfiguration; this.Request.TemplatePath = config.TemplatePath; this.Request.TemplateRelativePath = config.TemplateRelativePath; } With this data you can then configure any custom properties or objects on your main template class. It’s an easy way to pass data from the HostContainer all the way down into the template. The type you use is of type object so you have to cast it yourself, and it must be serializable since it will likely run in a separate AppDomain. This might seem like an ugly way to pass data around – normally I’d use an event delegate to call back from the engine to the host, but since this is running over AppDomain boundaries events get really tricky and passing a template instance back up into the host over AppDomain boundaries doesn’t work due to serialization issues. So it’s easier to pass the data from the host down into the template using this rather clumsy approach of set and forward. It’s ugly, but it’s something that can be hidden in the host container implementation as I’ve done here. It’s also not something you have to do in every implementation so this is kind of an edge case, but I know I’ll need to pass a bunch of data in some of my applications and this will be the easiest way to do so. Summing Up Hosting the Razor runtime is something I got jazzed up about quite a bit because I have an immediate need for this type of templating/merging/scripting capability in an application I’m working on. I’ve also been using templating in many apps and it’s always been a pain to deal with. The Razor engine makes this whole experience a lot cleaner and more light weight and with these wrappers I can now plug .NET based templating into my code literally with a few lines of code. That’s something to cheer about… I hope some of you will find this useful as well… Resources The examples and code require that you download the Razor runtimes. Projects are for Visual Studio 2010 running on .NET 4.0 Platform Installer 3.0 (install WebMatrix or MVC 3 for Razor Runtimes) Latest Code in Subversion Repository Download Snapshot of the Code Documentation (CHM Help File) © Rick Strahl, West Wind Technologies, 2005-2010Posted in ASP.NET  .NET  

    Read the article

  • Android app crashes on emulator - logCat shows no errors

    - by David Miler
    I have just added the SherlockActionBar library to my android project. After some small changes (FragmentActivity - SherlockFragmentActivity, getActionBar() - getSupportActionBar(), imports) it all compiled nicely. After I run the app, however, the debugger stops, as though it had encountered an exception. However, there are no errors shown in the LogCat output. I just can't wrap my head around what's going on. Here is the logCat output after I terminate the app. 10-02 14:11:19.227: I/SystemUpdateService(174): UpdateTask at time 1349187079227 10-02 14:11:19.237: I/ActivityThread(328): Pub com.android.email.attachmentprovider: com.android.email.provider.AttachmentProvider 10-02 14:11:19.687: I/dalvikvm(81): Jit: resizing JitTable from 512 to 1024 10-02 14:11:19.809: D/MediaScannerService(150): start scanning volume internal: [/system/media] 10-02 14:11:20.047: V/AlarmClock(239): AlarmInitReceiver finished 10-02 14:11:20.087: I/ActivityManager(81): Start proc com.android.quicksearchbox for broadcast com.android.quicksearchbox/.SearchWidgetProvider: pid=346 uid=10012 gids={3003} 10-02 14:11:20.127: D/ExchangeService(320): !!! EAS ExchangeService, onStartCommand, startingUp = false, running = false 10-02 14:11:20.427: I/ActivityThread(346): Pub com.android.quicksearchbox.google: com.android.quicksearchbox.google.GoogleSuggestionProvider 10-02 14:11:20.497: I/ActivityThread(346): Pub com.android.quicksearchbox.shortcuts: com.android.quicksearchbox.ShortcutsProvider 10-02 14:11:20.657: I/ActivityManager(81): Start proc com.android.music for broadcast com.android.music/.MediaAppWidgetProvider: pid=358 uid=10028 gids={3003, 1015} 10-02 14:11:20.927: D/ExchangeService(320): !!! EAS ExchangeService, onCreate 10-02 14:11:20.967: D/dalvikvm(260): GC_CONCURRENT freed 213K, 6% free 6409K/6791K, paused 5ms+101ms 10-02 14:11:21.077: D/ExchangeService(320): !!! EAS ExchangeService, onStartCommand, startingUp = true, running = false 10-02 14:11:21.567: D/GTalkService(174): [ReonnectMgr] ### report Inet condition: status=false, networkType=0 10-02 14:11:21.587: D/ConnectivityService(81): reportNetworkCondition(0, 0) 10-02 14:11:21.597: D/ConnectivityService(81): Inet connectivity change, net=0, condition=0,mActiveDefaultNetwork=0 10-02 14:11:21.597: D/ConnectivityService(81): starting a change hold 10-02 14:11:21.697: D/GTalkService(174): [RawStanzaProvidersMgr] ##### searchProvidersFromIntent 10-02 14:11:21.697: D/GTalkService(174): [RawStanzaProvidersMgr] no intent receivers found 10-02 14:11:21.847: I/SystemUpdateService(174): cancelUpdate (empty URL) 10-02 14:11:21.847: E/TelephonyManager(174): Hidden constructor called more than once per process! 10-02 14:11:21.867: D/dalvikvm(174): GC_CONCURRENT freed 337K, 7% free 6561K/7047K, paused 5ms+4ms 10-02 14:11:21.917: D/GTalkService(174): [ReonnectMgr] ### report Inet condition: status=false, networkType=0 10-02 14:11:21.917: D/ConnectivityService(81): reportNetworkCondition(0, 0) 10-02 14:11:21.917: D/ConnectivityService(81): Inet connectivity change, net=0, condition=0,mActiveDefaultNetwork=0 10-02 14:11:21.917: D/ConnectivityService(81): currently in hold - not setting new end evt 10-02 14:11:21.990: E/TelephonyManager(174): Original: com.google.android.location, new: com.google.android.gsf 10-02 14:11:22.027: I/SystemUpdateService(174): removeAllDownloads (cancelUpdate) 10-02 14:11:22.127: D/dalvikvm(328): GC_CONCURRENT freed 205K, 6% free 6506K/6855K, paused 660ms+3ms 10-02 14:11:22.197: D/Eas Debug(320): Logging: 10-02 14:11:22.319: D/dalvikvm(81): GREF has increased to 401 10-02 14:11:22.947: D/ExchangeService(320): !!! EAS ExchangeService, onStartCommand, startingUp = true, running = false 10-02 14:11:23.130: D/Eas Debug(320): Logging: 10-02 14:11:23.307: I//system/bin/fsck_msdos(29): Attempting to allocate 2044 KB for FAT 10-02 14:11:23.560: I/ActivityManager(81): Starting: Intent { flg=0x10000000 cmp=com.google.android.gsf/.update.SystemUpdateInstallDialog } from pid 174 10-02 14:11:23.587: I/ActivityManager(81): Starting: Intent { flg=0x10000000 cmp=com.google.android.gsf/.update.SystemUpdateDownloadDialog } from pid 174 10-02 14:11:24.087: W/ActivityManager(81): Activity pause timeout for ActivityRecord{407c7320 com.android.launcher/com.android.launcher2.Launcher} 10-02 14:11:24.237: E/TelephonyManager(174): Hidden constructor called more than once per process! 10-02 14:11:24.237: E/TelephonyManager(174): Original: com.google.android.location, new: com.google.android.gsf 10-02 14:11:24.507: D/dalvikvm(174): GC_EXPLICIT freed 231K, 7% free 6596K/7047K, paused 4ms+6ms 10-02 14:11:24.607: D/ConnectivityService(81): Inet hold end, net=0, condition =0, published condition =0 10-02 14:11:24.607: D/ConnectivityService(81): no change in condition - aborting 10-02 14:11:24.707: D/dalvikvm(174): GC_EXPLICIT freed 17K, 7% free 6579K/7047K, paused 4ms+4ms 10-02 14:11:24.947: I//system/bin/fsck_msdos(29): ** Phase 2 - Check Cluster Chains 10-02 14:11:25.117: I//system/bin/fsck_msdos(29): ** Phase 3 - Checking Directories 10-02 14:11:25.128: I//system/bin/fsck_msdos(29): ** Phase 4 - Checking for Lost Files 10-02 14:11:25.167: I//system/bin/fsck_msdos(29): 12 files, 1044448 free (522224 clusters) 10-02 14:11:25.227: I/Vold(29): Filesystem check completed OK 10-02 14:11:25.227: I/Vold(29): Device /dev/block/vold/179:0, target /mnt/sdcard mounted @ /mnt/secure/staging 10-02 14:11:25.237: D/Vold(29): Volume sdcard state changing 3 (Checking) -> 4 (Mounted) 10-02 14:11:25.257: I/PackageManager(81): Updating external media status from unmounted to mounted 10-02 14:11:25.457: D/dalvikvm(303): GC_EXPLICIT freed 35K, 6% free 6242K/6595K, paused 3ms+312ms 10-02 14:11:25.987: D/ExchangeService(320): !!! EAS ExchangeService, onStartCommand, startingUp = true, running = false 10-02 14:11:26.157: D/MediaScanner(150): prescan time: 2905ms 10-02 14:11:26.167: D/MediaScanner(150): scan time: 148ms 10-02 14:11:26.167: D/MediaScanner(150): postscan time: 2ms 10-02 14:11:26.167: D/MediaScanner(150): total time: 3055ms 10-02 14:11:26.197: D/MediaScannerService(150): done scanning volume internal 10-02 14:11:26.237: D/MediaScannerService(150): start scanning volume external: [/mnt/sdcard] 10-02 14:11:26.497: D/dalvikvm(143): GC_EXPLICIT freed 234K, 8% free 7735K/8327K, paused 3ms+5ms 10-02 14:11:27.180: D/dalvikvm(143): GC_CONCURRENT freed 150K, 4% free 8004K/8327K, paused 7ms+3ms 10-02 14:11:27.397: D/dalvikvm(143): GC_FOR_ALLOC freed 96K, 6% free 8310K/8775K, paused 76ms 10-02 14:11:27.580: D/dalvikvm(143): GC_FOR_ALLOC freed 515K, 11% free 8135K/9095K, paused 79ms 10-02 14:11:27.829: D/dalvikvm(143): GC_CONCURRENT freed 3K, 5% free 8694K/9095K, paused 7ms+6ms 10-02 14:11:28.137: V/TLINE(143): new: android.text.TextLine@4065b280 10-02 14:11:28.527: D/dalvikvm(143): GC_CONCURRENT freed 729K, 10% free 8764K/9671K, paused 5ms+13ms 10-02 14:11:28.677: D/dalvikvm(143): GC_FOR_ALLOC freed 152K, 11% free 8683K/9671K, paused 99ms 10-02 14:11:28.717: I/dalvikvm-heap(143): Grow heap (frag case) to 11.434MB for 2975968-byte allocation 10-02 14:11:28.807: D/dalvikvm(143): GC_FOR_ALLOC freed 0K, 9% free 11589K/12615K, paused 84ms 10-02 14:11:29.159: D/dalvikvm(143): GC_CONCURRENT freed 197K, 7% free 12195K/12999K, paused 8ms+6ms 10-02 14:11:29.647: D/dalvikvm(143): GC_EXPLICIT freed 351K, 6% free 12790K/13511K, paused 8ms+17ms 10-02 14:11:29.717: I/SurfaceFlinger(32): Boot is finished (70768 ms) 10-02 14:11:29.877: I/ARMAssembler(32): generated scanline__00000177:03010104_00000002_00000000 [ 44 ipp] (66 ins) at [0x407c7290:0x407c7398] in 990662 ns 10-02 14:11:29.907: I/ARMAssembler(32): generated scanline__00000177:03515104_00000001_00000000 [ 73 ipp] (95 ins) at [0x407c73a0:0x407c751c] in 989381 ns 10-02 14:11:30.287: D/dalvikvm(174): GC_EXPLICIT freed 25K, 8% free 6554K/7047K, paused 4ms+32ms 10-02 14:11:30.380: D/dalvikvm(143): GC_EXPLICIT freed 349K, 6% free 13124K/13895K, paused 5ms+25ms 10-02 14:11:30.957: D/dalvikvm(143): GC_FOR_ALLOC freed 1069K, 10% free 13860K/15239K, paused 81ms 10-02 14:11:32.177: D/dalvikvm(150): GC_CONCURRENT freed 183K, 6% free 6438K/6791K, paused 5ms+4ms 10-02 14:11:32.187: W/ActivityManager(81): No content provider found for: 10-02 14:11:32.607: V/MediaScanner(150): pruneDeadThumbnailFiles... android.database.sqlite.SQLiteCursor@406724a8 10-02 14:11:32.617: V/MediaScanner(150): /pruneDeadThumbnailFiles... android.database.sqlite.SQLiteCursor@406724a8 10-02 14:11:32.640: W/ActivityManager(81): No content provider found for: 10-02 14:11:32.640: D/VoldCmdListener(29): asec list 10-02 14:11:32.647: I/PackageManager(81): No secure containers on sdcard 10-02 14:11:32.667: D/MediaScanner(150): prescan time: 107ms 10-02 14:11:32.667: D/MediaScanner(150): scan time: 89ms 10-02 14:11:32.667: D/MediaScanner(150): postscan time: 61ms 10-02 14:11:32.667: D/MediaScanner(150): total time: 257ms 10-02 14:11:32.697: W/PackageManager(81): Unknown permission android.permission.ADD_SYSTEM_SERVICE in package com.android.phone 10-02 14:11:32.707: W/PackageManager(81): Unknown permission com.android.smspush.WAPPUSH_MANAGER_BIND in package com.android.phone 10-02 14:11:32.737: W/PackageManager(81): Not granting permission android.permission.SEND_DOWNLOAD_COMPLETED_INTENTS to package com.android.browser (protectionLevel=2 flags=0x9be45) 10-02 14:11:32.737: W/PackageManager(81): Not granting permission android.permission.BIND_APPWIDGET to package com.android.widgetpreview (protectionLevel=3 flags=0x28be44) 10-02 14:11:32.767: W/PackageManager(81): Unknown permission android.permission.READ_OWNER_DATA in package com.android.exchange 10-02 14:11:32.778: W/PackageManager(81): Unknown permission android.permission.READ_OWNER_DATA in package com.android.email 10-02 14:11:32.788: W/PackageManager(81): Unknown permission com.android.providers.im.permission.READ_ONLY in package com.google.android.apps.maps 10-02 14:11:32.797: W/PackageManager(81): Not granting permission android.permission.DEVICE_POWER to package com.android.deskclock (protectionLevel=2 flags=0x8be45) 10-02 14:11:33.137: D/MediaScannerService(150): done scanning volume external 10-02 14:11:33.197: D/PackageParser(81): Scanning package: /data/app/vmdl257911298.tmp 10-02 14:11:33.837: I/InputReader(81): Device reconfigured: id=0, name='qwerty2', surface size is now 1024x800 10-02 14:11:34.097: D/dalvikvm(81): GC_CONCURRENT freed 12185K, 47% free 13966K/26311K, paused 8ms+23ms 10-02 14:11:36.798: I/TabletStatusBar(124): DISABLE_CLOCK: no 10-02 14:11:36.798: I/TabletStatusBar(124): DISABLE_NAVIGATION: no 10-02 14:11:37.348: I/ARMAssembler(32): generated scanline__00000177:03515104_00001001_00000000 [ 91 ipp] (114 ins) at [0x407c7520:0x407c76e8] in 919320 ns 10-02 14:11:37.598: I/TabletStatusBar(124): DISABLE_BACK: no 10-02 14:11:37.710: I/ActivityManager(81): Displayed com.android.launcher/com.android.launcher2.Launcher: +46s212ms 10-02 14:11:38.817: D/dalvikvm(143): GC_CONCURRENT freed 969K, 8% free 14867K/16007K, paused 4ms+10ms 10-02 14:11:39.437: I/dalvikvm(81): Jit: resizing JitTable from 1024 to 2048 10-02 14:11:40.267: D/dalvikvm(143): GC_FOR_ALLOC freed 2357K, 16% free 14395K/17031K, paused 80ms 10-02 14:11:40.717: D/dalvikvm(143): GC_EXPLICIT freed 742K, 16% free 14358K/17031K, paused 8ms+4ms 10-02 14:11:41.617: D/dalvikvm(81): GC_CONCURRENT freed 1955K, 48% free 13869K/26311K, paused 9ms+10ms 10-02 14:11:42.559: D/dalvikvm(81): GC_CONCURRENT freed 1830K, 48% free 13881K/26311K, paused 9ms+9ms 10-02 14:11:42.758: I/PackageManager(81): Removing non-system package:cz.trilimi.sfaui 10-02 14:11:42.758: I/ActivityManager(81): Force stopping package cz.trilimi.sfaui uid=10036 10-02 14:11:42.967: D/PackageManager(81): Scanning package cz.trilimi.sfaui 10-02 14:11:42.967: I/PackageManager(81): Package cz.trilimi.sfaui codePath changed from /data/app/cz.trilimi.sfaui-1.apk to /data/app/cz.trilimi.sfaui-2.apk; Retaining data and using new 10-02 14:11:42.967: I/PackageManager(81): Unpacking native libraries for /data/app/cz.trilimi.sfaui-2.apk 10-02 14:11:43.097: D/installd(35): DexInv: --- BEGIN '/data/app/cz.trilimi.sfaui-2.apk' --- 10-02 14:11:45.317: D/dalvikvm(391): DexOpt: load 434ms, verify+opt 1260ms 10-02 14:11:45.407: D/installd(35): DexInv: --- END '/data/app/cz.trilimi.sfaui-2.apk' (success) --- 10-02 14:11:45.407: W/PackageManager(81): Code path for pkg : cz.trilimi.sfaui changing from /data/app/cz.trilimi.sfaui-1.apk to /data/app/cz.trilimi.sfaui-2.apk 10-02 14:11:45.407: W/PackageManager(81): Resource path for pkg : cz.trilimi.sfaui changing from /data/app/cz.trilimi.sfaui-1.apk to /data/app/cz.trilimi.sfaui-2.apk 10-02 14:11:45.407: D/PackageManager(81): Activities: cz.trilimi.sfaui.ItemListActivity cz.trilimi.sfaui.ItemDetailActivity 10-02 14:11:45.427: I/ActivityManager(81): Force stopping package cz.trilimi.sfaui uid=10036 10-02 14:11:45.657: I/installd(35): move /data/dalvik-cache/data@[email protected]@classes.dex -> /data/dalvik-cache/data@[email protected]@classes.dex 10-02 14:11:45.657: D/PackageManager(81): New package installed in /data/app/cz.trilimi.sfaui-2.apk 10-02 14:11:45.997: I/ActivityManager(81): Force stopping package cz.trilimi.sfaui uid=10036 10-02 14:11:46.147: D/dalvikvm(143): GC_EXPLICIT freed 3K, 16% free 14356K/17031K, paused 10ms+9ms 10-02 14:11:46.237: D/PackageManager(81): generateServicesMap(android.accounts.AccountAuthenticator): 3 services unchanged 10-02 14:11:46.277: D/PackageManager(81): generateServicesMap(android.content.SyncAdapter): 5 services unchanged 10-02 14:11:46.337: D/PackageManager(81): generateServicesMap(android.accounts.AccountAuthenticator): 3 services unchanged 10-02 14:11:46.347: D/PackageManager(81): generateServicesMap(android.content.SyncAdapter): 5 services unchanged 10-02 14:11:46.437: D/dalvikvm(208): GC_EXPLICIT freed 258K, 7% free 6488K/6919K, paused 3ms+5ms 10-02 14:11:46.477: W/RecognitionManagerService(81): no available voice recognition services found 10-02 14:11:46.897: I/ActivityManager(81): Start proc com.svox.pico for broadcast com.svox.pico/.VoiceDataInstallerReceiver: pid=398 uid=10006 gids={} 10-02 14:11:47.087: I/ActivityThread(398): Pub com.svox.pico.providers.SettingsProvider: com.svox.pico.providers.SettingsProvider 10-02 14:11:47.138: D/GTalkService(174): [GTalkService.1] handlePackageInstalled: re-initialize providers 10-02 14:11:47.147: D/GTalkService(174): [RawStanzaProvidersMgr] ##### searchProvidersFromIntent 10-02 14:11:47.147: D/GTalkService(174): [RawStanzaProvidersMgr] no intent receivers found 10-02 14:11:47.718: I/AccountTypeManager(208): Loaded meta-data for 1 account types, 0 accounts in 186ms 10-02 14:11:48.377: D/dalvikvm(143): GC_CONCURRENT freed 1865K, 15% free 14513K/17031K, paused 7ms+4ms 10-02 14:11:48.917: D/dalvikvm(208): GC_CONCURRENT freed 219K, 6% free 6788K/7175K, paused 7ms+73ms 10-02 14:11:49.207: D/dalvikvm(143): GC_FOR_ALLOC freed 4558K, 31% free 11866K/17031K, paused 89ms 10-02 14:11:49.587: D/dalvikvm(143): GC_CONCURRENT freed 713K, 24% free 13010K/17031K, paused 5ms+4ms 10-02 14:11:49.967: D/dalvikvm(143): GC_CONCURRENT freed 1046K, 19% free 13922K/17031K, paused 5ms+4ms 10-02 14:11:50.437: D/dalvikvm(81): GC_EXPLICIT freed 898K, 47% free 13955K/26311K, paused 6ms+39ms 10-02 14:11:50.467: I/installd(35): unlink /data/dalvik-cache/data@[email protected]@classes.dex 10-02 14:11:50.477: D/AndroidRuntime(227): Shutting down VM 10-02 14:11:50.507: D/dalvikvm(227): GC_CONCURRENT freed 97K, 84% free 331K/2048K, paused 1ms+2ms 10-02 14:11:50.507: I/AndroidRuntime(227): NOTE: attach of thread 'Binder Thread #3' failed 10-02 14:11:50.517: D/jdwp(227): adbd disconnected 10-02 14:11:51.177: D/AndroidRuntime(410): >>>>>> AndroidRuntime START com.android.internal.os.RuntimeInit <<<<<< 10-02 14:11:51.177: D/AndroidRuntime(410): CheckJNI is ON 10-02 14:11:51.897: D/AndroidRuntime(410): Calling main entry com.android.commands.am.Am 10-02 14:11:51.937: I/ActivityManager(81): Force stopping package cz.trilimi.sfaui uid=10036 10-02 14:11:51.937: I/ActivityManager(81): Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=cz.trilimi.sfaui/.ItemListActivity } from pid 410 10-02 14:11:51.968: W/WindowManager(81): Failure taking screenshot for (230x179) to layer 21005 10-02 14:11:51.997: I/ActivityManager(81): Start proc cz.trilimi.sfaui for activity cz.trilimi.sfaui/.ItemListActivity: pid=418 uid=10036 gids={} 10-02 14:11:52.007: D/AndroidRuntime(410): Shutting down VM 10-02 14:11:52.057: I/AndroidRuntime(410): NOTE: attach of thread 'Binder Thread #3' failed 10-02 14:11:52.097: D/dalvikvm(410): GC_CONCURRENT freed 98K, 83% free 360K/2048K, paused 1ms+0ms 10-02 14:11:52.097: D/jdwp(410): adbd disconnected 10-02 14:11:53.147: W/ActivityThread(418): Application cz.trilimi.sfaui is waiting for the debugger on port 8100... 10-02 14:11:53.207: I/System.out(418): Sending WAIT chunk 10-02 14:11:53.217: I/dalvikvm(418): Debugger is active 10-02 14:11:53.447: I/System.out(418): Debugger has connected 10-02 14:11:53.457: I/System.out(418): waiting for debugger to settle... 10-02 14:11:53.637: I/ARMAssembler(32): generated scanline__00000177:03515104_00001002_00000000 [ 87 ipp] (110 ins) at [0x407c76f0:0x407c78a8] in 598498 ns 10-02 14:11:53.660: I/System.out(418): waiting for debugger to settle... 10-02 14:11:53.857: I/System.out(418): waiting for debugger to settle... 10-02 14:11:54.057: I/System.out(418): waiting for debugger to settle... 10-02 14:11:54.257: I/System.out(418): waiting for debugger to settle... 10-02 14:11:54.317: V/TLINE(81): new: android.text.TextLine@4155dde8 10-02 14:11:54.467: I/System.out(418): waiting for debugger to settle... 10-02 14:11:54.667: I/System.out(418): waiting for debugger to settle... 10-02 14:11:54.870: I/System.out(418): waiting for debugger to settle... 10-02 14:11:55.027: D/dalvikvm(143): GC_EXPLICIT freed 900K, 16% free 14420K/17031K, paused 7ms+4ms 10-02 14:11:55.067: I/System.out(418): waiting for debugger to settle... 10-02 14:11:55.292: I/System.out(418): debugger has settled (1315) 10-02 14:12:02.008: W/ActivityManager(81): Launch timeout has expired, giving up wake lock! 10-02 14:12:02.971: W/ActivityManager(81): Activity idle timeout for ActivityRecord{4078c6b0 cz.trilimi.sfaui/.ItemListActivity} 10-02 14:12:08.359: D/ExchangeService(320): Received deviceId from Email app: androidc259148960 10-02 14:12:08.507: D/ExchangeService(320): Reconciling accounts... 10-02 14:16:11.437: D/SntpClient(81): request time failed: java.net.SocketException: Address family not supported by protocol 10-02 14:17:21.573: W/jdwp(418): Debugger is telling the VM to exit with code=1 10-02 14:17:21.573: I/dalvikvm(418): GC lifetime allocation: 8642 bytes 10-02 14:17:21.637: D/Zygote(33): Process 418 exited cleanly (1) 10-02 14:17:21.651: I/ActivityManager(81): Process cz.trilimi.sfaui (pid 418) has died. 10-02 14:17:21.847: D/dalvikvm(143): GC_EXPLICIT freed <1K, 16% free 14420K/17031K, paused 7ms+7ms 10-02 14:17:21.917: W/InputManagerService(81): Window already focused, ignoring focus gain of: com.android.internal.view.IInputMethodClient$Stub$Proxy@40bfbf28

    Read the article

  • Thread not behaving correctly

    - by ivor
    Hello, I wonder if anyone can help me to understand where I could be going wrong with this code; Basically I'm working on a turorial and calling the class below from another class - and it is getting the following error; Exception in thread "Thread-1" java.lang.NullPointerException at org.newdawn.spaceinvaders.TCPChat.run(TCPChat.java:322) at java.lang.Thread.run(Unknown Source) I realise the error is beibg flagged in another class- but I have tested the other class with a small class which sets up a separate thread - and it works fine, but as soon as I try and implement a new thread in this class - it causes all sorts of problems. Am I setting up the thread correctly in this class? Basically I can set up a thread in this class, with a test loop and it's fine, but when I bring in the functionality of the rest of the game it sometimes hangs, or does not display at all. Any suggestions on where I could be going wrong would be greatly appreciated. Thanks for looking. package org.newdawn.spaceinvaders; import java.awt.BorderLayout; import java.awt.Canvas; import java.awt.Color; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Graphics2D; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.image.BufferStrategy; import java.util.ArrayList; import java.util.Scanner; import java.awt.*;//maybe not needed import javax.swing.*;//maybenot needed import java.util.Random; //import java.io.*; /** * The main hook of our game. This class with both act as a manager * for the display and central mediator for the game logic. * * Display management will consist of a loop that cycles round all * entities in the game asking them to move and then drawing them * in the appropriate place. With the help of an inner class it * will also allow the player to control the main ship. * * As a mediator it will be informed when entities within our game * detect events (e.g. alient killed, played died) and will take * appropriate game actions. * * @author Kevin Glass */ public class Game extends Canvas implements Runnable{ /** The stragey that allows us to use accelerate page flipping */ private BufferStrategy strategy; /** True if the game is currently "running", i.e. the game loop is looping */ private boolean gameRunning = true; /** The list of all the entities that exist in our game */ private ArrayList entities = new ArrayList(); /** The list of entities that need to be removed from the game this loop */ private ArrayList removeList = new ArrayList(); /** The entity representing the player */ private Entity ship; /** The speed at which the player's ship should move (pixels/sec) */ private double moveSpeed = 300; /** The time at which last fired a shot */ private long lastFire = 0; /** The interval between our players shot (ms) */ private long firingInterval = 500; /** The number of aliens left on the screen */ private int alienCount; /** The number of levels progressed */ private double levelCount; /** high score for the user */ private int highScore; /** high score for the user */ private String player = "bob"; //private GetUserInput getPlayer; /** The list of entities that need to be removed from the game this loop */ /** The message to display which waiting for a key press */ private String message = ""; /** True if we're holding up game play until a key has been pressed */ private boolean waitingForKeyPress = true; /** True if the left cursor key is currently pressed */ private boolean leftPressed = false; /** True if the right cursor key is currently pressed */ private boolean rightPressed = false; /** True if we are firing */ private boolean firePressed = false; /** True if game logic needs to be applied this loop, normally as a result of a game event */ private boolean logicRequiredThisLoop = false; //private Thread cThread = new Thread(this); //public Thread t = new Thread(this); //private Thread g = new Thread(this); void setHighscore(int setHS) { highScore = setHS; } public int getHighscore() { return highScore; } public void setPlayer(String setPlayer) { player = setPlayer; } public String getPlayer() { return player; } public void run() { //setup(); System.out.println("hello im running bob"); /*int count = 1; do { System.out.println("Count is: " + count); count++; try{Thread.sleep(1);} catch(InterruptedException e){} } while (count <= 2000000);*/ //Game g =new Game(); //Game g = this; // Start the main game loop, note: this method will not // return until the game has finished running. Hence we are // using the actual main thread to run the game. //setup(); //this.gameLoop(); //try{thread.sleep(1);} //catch{InterruptedException e} } /** * Construct our game and set it running. */ public Game () { //Thread t = new Thread(this);//set up new thread for invaders game //t.run();//run the run method of the game //Game g =new Game(); //setup(); //Thread t = new Thread(this); //thread.start(); //SwingUtilities.invokeLater(this); Thread er = new Thread(this); er.start(); } public void setup(){ //initialise highscore setHighscore(0); // create a frame to contain our game JFrame container = new JFrame("Space Invaders 101"); // get hold the content of the frame and set up the resolution of the game JPanel panel = (JPanel) container.getContentPane(); panel.setPreferredSize(new Dimension(800,600)); //panel.setLayout(null); // setup our canvas size and put it into the content of the frame setBounds(0,0,800,600); panel.add(this); // Tell AWT not to bother repainting our canvas since we're // going to do that our self in accelerated mode setIgnoreRepaint(true); // finally make the window visible container.pack(); container.setResizable(false); container.setVisible(true); // add a listener to respond to the user closing the window. If they // do we'd like to exit the game container.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { //cThread.interrupt(); System.exit(0); } }); // add a key input system (defined below) to our canvas // so we can respond to key pressed addKeyListener(new KeyInputHandler()); // request the focus so key events come to us requestFocus(); // create the buffering strategy which will allow AWT // to manage our accelerated graphics createBufferStrategy(2); strategy = getBufferStrategy(); // initialise the entities in our game so there's something // to see at startup initEntities(); } /** * Start a fresh game, this should clear out any old data and * create a new set. */ private void startGame() { // clear out any existing entities and intialise a new set entities.clear(); initEntities(); //initialise highscore setHighscore(0); // blank out any keyboard settings we might currently have leftPressed = false; rightPressed = false; firePressed = false; } /** * Initialise the starting state of the entities (ship and aliens). Each * entitiy will be added to the overall list of entities in the game. */ //private void initEntities() { public void initEntities() { Random randomAlien = new Random(); // create the player ship and place it roughly in the center of the screen //ship = new ShipEntity(this,"sprites/ship.gif",370,550);//orignal ship = new ShipEntity(this,"sprites/ship.gif",700,300);//changed postioning to right hand side entities.add(ship); // create a block of aliens (5 rows, by 12 aliens, spaced evenly) alienCount = 0; levelCount = 1.02; for (int row=0;row<7;row++) {//altered number of rows for (int x=0;x<5;x++) { int r = randomAlien.nextInt(100);//loop added to produce random aliens if (r < 50){ //Entity alien = new AlienEntity(this,"sprites/alien.gif",/*100+*/(x*50),(50)+row*30); Entity alien = new AlienEntity(this,"sprites/alien.gif",100+(x*90),(12)+row*85); entities.add(alien); alienCount++; } } } } //private void initEntities() { public void initAlienEntities() { Random randomAlien = new Random(); // create the player ship and place it roughly in the center of the screen //ship = new ShipEntity(this,"sprites/ship.gif",370,550);//orignal //ship = new ShipEntity(this,"sprites/ship.gif",700,300);//changed postioning to right hand side //entities.add(ship); // create a block of aliens (5 rows, by 12 aliens, spaced evenly) alienCount = 0; levelCount = levelCount + 0.10;//this increases the speed on every level for (int row=0;row<7;row++) {//altered number of rows for (int x=0;x<5;x++) { int r = randomAlien.nextInt(100);//loop added to produce random aliens if (r < 50){//randome check to show alien //Entity alien = new AlienEntity(this,"sprites/alien.gif",/*100+*/(x*50),(50)+row*30); Entity alien = new AlienEntity(this,"sprites/alien.gif",-250+(x*90),(12)+row*85); entities.add(alien); alienCount++; } } } advanceAlienSpeed(levelCount); } /** * Notification from a game entity that the logic of the game * should be run at the next opportunity (normally as a result of some * game event) */ public void updateLogic() { logicRequiredThisLoop = true; } /** * Remove an entity from the game. The entity removed will * no longer move or be drawn. * * @param entity The entity that should be removed */ public void removeEntity(Entity entity) { removeList.add(entity); } /** * Notification that the player has died. */ public void notifyDeath() { message = "Oh no! They got you, try again?"; waitingForKeyPress = true; } /** * Notification that the player has won since all the aliens * are dead. */ public void notifyWin() { message = "Well done! You Win!"; waitingForKeyPress = true; } /** * Notification that an alien has been killed */ public void notifyAlienKilled() { // reduce the alient count, if there are none left, the player has won! alienCount--; if (alienCount == 0) { //notifyWin();win not relevant here... this.initAlienEntities();//call fresh batch of aliens } // if there are still some aliens left then they all need to get faster, so // speed up all the existing aliens advanceAlienSpeed(1.30); } public void advanceAlienSpeed(double speed) { // if there are still some aliens left then they all need to get faster, so // speed up all the existing aliens for (int i=0;i<entities.size();i++) { Entity entity = (Entity) entities.get(i); if (entity instanceof AlienEntity) { // speed up by 2% entity.setHorizontalMovement(entity.getHorizontalMovement() * speed); //entity.setVerticalMovement(entity.getVerticalMovement() * 1.02); } } } /** * Attempt to fire a shot from the player. Its called "try" * since we must first check that the player can fire at this * point, i.e. has he/she waited long enough between shots */ public void tryToFire() { // check that we have waiting long enough to fire if (System.currentTimeMillis() - lastFire < firingInterval) { return; } // if we waited long enough, create the shot entity, and record the time. lastFire = System.currentTimeMillis(); ShotEntity shot = new ShotEntity(this,"sprites/shot.gif",ship.getX()+10,ship.getY()-30); entities.add(shot); } /** * The main game loop. This loop is running during all game * play as is responsible for the following activities: * <p> * - Working out the speed of the game loop to update moves * - Moving the game entities * - Drawing the screen contents (entities, text) * - Updating game events * - Checking Input * <p> */ public void gameLoop() { long lastLoopTime = System.currentTimeMillis(); // keep looping round til the game ends while (gameRunning) { // work out how long its been since the last update, this // will be used to calculate how far the entities should // move this loop long delta = System.currentTimeMillis() - lastLoopTime; lastLoopTime = System.currentTimeMillis(); // Get hold of a graphics context for the accelerated // surface and blank it out Graphics2D g = (Graphics2D) strategy.getDrawGraphics(); g.setColor(Color.black); g.fillRect(0,0,800,600); // cycle round asking each entity to move itself if (!waitingForKeyPress) { for (int i=0;i<entities.size();i++) { Entity entity = (Entity) entities.get(i); entity.move(delta); } } // cycle round drawing all the entities we have in the game for (int i=0;i<entities.size();i++) { Entity entity = (Entity) entities.get(i); entity.draw(g); } // brute force collisions, compare every entity against // every other entity. If any of them collide notify // both entities that the collision has occured for (int p=0;p<entities.size();p++) { for (int s=p+1;s<entities.size();s++) { Entity me = (Entity) entities.get(p); Entity him = (Entity) entities.get(s); if (me.collidesWith(him)) { me.collidedWith(him); him.collidedWith(me); } } } // remove any entity that has been marked for clear up entities.removeAll(removeList); removeList.clear(); // if a game event has indicated that game logic should // be resolved, cycle round every entity requesting that // their personal logic should be considered. if (logicRequiredThisLoop) { //g.drawString("Press any key",(800-g.getFontMetrics().stringWidth("Press any key"))/2,300); for (int i=0;i<entities.size();i++) { Entity entity = (Entity) entities.get(i); entity.doLogic(); } logicRequiredThisLoop = false; } // if we're waiting for an "any key" press then draw the // current message //show highscore at top of screen //show name at top of screen g.setColor(Color.white); g.drawString("Player : "+getPlayer()+" : Score : "+getHighscore(),20,20); if (waitingForKeyPress) { g.setColor(Color.white); g.drawString(message,(800-g.getFontMetrics().stringWidth(message))/2,250); g.drawString("Press any key",(800-g.getFontMetrics().stringWidth("Press any key"))/2,300); } // finally, we've completed drawing so clear up the graphics // and flip the buffer over g.dispose(); strategy.show(); // resolve the movement of the ship. First assume the ship // isn't moving. If either cursor key is pressed then // update the movement appropraitely ship.setVerticalMovement(0);//set to vertical movement if ((leftPressed) && (!rightPressed)) { ship.setVerticalMovement(-moveSpeed);//**took out setHorizaontalMOvement } else if ((rightPressed) && (!leftPressed)) { ship.setVerticalMovement(moveSpeed);//**took out setHorizaontalMOvement } // if we're pressing fire, attempt to fire if (firePressed) { tryToFire(); } // finally pause for a bit. Note: this should run us at about // 100 fps but on windows this might vary each loop due to // a bad implementation of timer try { Thread.sleep(10); } catch (Exception e) {} } } /** * A class to handle keyboard input from the user. The class * handles both dynamic input during game play, i.e. left/right * and shoot, and more static type input (i.e. press any key to * continue) * * This has been implemented as an inner class more through * habbit then anything else. Its perfectly normal to implement * this as seperate class if slight less convienient. * * @author Kevin Glass */ private class KeyInputHandler extends KeyAdapter { /** The number of key presses we've had while waiting for an "any key" press */ private int pressCount = 1; /** * Notification from AWT that a key has been pressed. Note that * a key being pressed is equal to being pushed down but *NOT* * released. Thats where keyTyped() comes in. * * @param e The details of the key that was pressed */ public void keyPressed(KeyEvent e) { // if we're waiting for an "any key" typed then we don't // want to do anything with just a "press" if (waitingForKeyPress) { return; } // if (e.getKeyCode() == KeyEvent.VK_LEFT) { ////leftPressed = true; ///} //// if (e.getKeyCode() == KeyEvent.VK_RIGHT) { //rightPressed = true; if (e.getKeyCode() == KeyEvent.VK_UP) { leftPressed = true; } if (e.getKeyCode() == KeyEvent.VK_DOWN) { rightPressed = true; } if (e.getKeyCode() == KeyEvent.VK_SPACE) { firePressed = true; } } /** * Notification from AWT that a key has been released. * * @param e The details of the key that was released */ public void keyReleased(KeyEvent e) { // if we're waiting for an "any key" typed then we don't // want to do anything with just a "released" if (waitingForKeyPress) { return; } if (e.getKeyCode() == KeyEvent.VK_UP) {//changed from VK_LEFT leftPressed = false; } if (e.getKeyCode() == KeyEvent.VK_DOWN) {//changed from VK_RIGHT rightPressed = false; } if (e.getKeyCode() == KeyEvent.VK_SPACE) { firePressed = false; } } /** * Notification from AWT that a key has been typed. Note that * typing a key means to both press and then release it. * * @param e The details of the key that was typed. */ public void keyTyped(KeyEvent e) { // if we're waiting for a "any key" type then // check if we've recieved any recently. We may // have had a keyType() event from the user releasing // the shoot or move keys, hence the use of the "pressCount" // counter. if (waitingForKeyPress) { if (pressCount == 1) { // since we've now recieved our key typed // event we can mark it as such and start // our new game waitingForKeyPress = false; startGame(); pressCount = 0; } else { pressCount++; } } // if we hit escape, then quit the game if (e.getKeyChar() == 27) { //cThread.interrupt(); System.exit(0); } } } /** * The entry point into the game. We'll simply create an * instance of class which will start the display and game * loop. * * @param argv The arguments that are passed into our game */ //public static void main(String argv[]) { //Game g =new Game(); // Start the main game loop, note: this method will not // return until the game has finished running. Hence we are // using the actual main thread to run the game. //g.gameLoop(); //} }

    Read the article

  • Modifying a HTML page to fix several "bugs" add a function to next/previous on a option dropdown

    - by Dennis Sylvian
    SOF, I've got a few problems plaguing me at the moment and am wondering if anyone could assist me with them. I'm trying to get Next Class | Previous Class to act as buttons so that when Next Class is clicked it will go to the next item in the dropdown list and for previous it would go to back one. There used to be a scroll bar that allowed me to scroll the main window left and right, it's missing because (I think it was to do with the scroll left and scroll right function) The footer at the bottom doesn't show correctly on mobile devices; for some reason it appears completely differently to as it does on a computer. The "bar" practically and the Scroll Left and Scroll buttons don't appear at all on mobile devices. The scroll left button is unable to be clicked for some reason, I'm unsure what I've done wrong. Refreshing the page resets the horizontal scroll position to far left (I'm pretty sure this relates to the scroll bar) I want to also find a way so that on mobile devices the the header will not show the placeholder image, however I can't work out what CSS media tag(s) I should be using. Latest: http://jsfiddle.net/pwv7u/ Smaller HTML <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>DATA DATA DATA DATA DATA DATA DATA DATA</title> <style type="text/css"> <!-- @import url("nstyle.css"); --> </style> <script src="jquery.min.js" type="text/javascript"></script> <script type="text/javascript"> $(document).ready( function() { for (var i=0;i<($("table").children().length);i++){ if(readCookie(i)) $($($("table").children()[i]).children()[(readCookie(i))]).toggleClass('selected').siblings().removeClass('selected'); } $("tr").click(function(){ $(this).toggleClass('selected').siblings().removeClass('selected'); if(readCookie($(this).parent().index())){ if(readCookie($(this).parent().index())==$(this).index()) eraseCookie($(this).parent().index()); else{ eraseCookie($(this).parent().index()); createCookie($(this).parent().index(),$(this).index(),1); } } else createCookie($(this).parent().index(),$(this).index(),1); }); // gather CLASS info var selector = $('.class-selector').on('change', function(){ var id = this.value; if (id!==''){ scrollToAnchor(id); } }); $('a[id^="CLASS"]').each(function(){ var id = this.id, option = $('<option>',{ value: this.id, text:this.id }); selector.append(option); }); function scrollToAnchor(aid) { var aTag = $("a[id='" + aid + "']"); $('html,body').animate({ scrollTop: aTag.offset().top - 80 }, 1); } $("a.TOPJS").click(function () { scrollToAnchor('TOP'); }); $("a.KEYJS").click(function () { scrollToAnchor('KEY'); }); $("a.def").click(function () { $('#container').animate({ "scrollLeft": "-=204" }, 200); }); $("a.abc").click(function () { $("#container").animate({ "scrollLeft": "+=204" }, 200); }); function createCookie(name,value,days) { var expires; if (days) { var date = new Date(); date.setMilliseconds(0); date.setSeconds(0); date.setMinutes(0); date.setHours(0); date.setDate(date.getDate()+days); expires = "; expires="+date.toGMTString(); } else expires = ""; document.cookie = name+"="+value+expires+"; path=/"; } function readCookie(name) { var nameEQ = name + "="; var ca = document.cookie.split(';'); for(var i=0;i < ca.length;i++) { var c = ca[i]; while (c.charAt(0)==' ') c = c.substring(1,c.length); if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length,c.length); } return null; } function eraseCookie(name) { createCookie(name,"",-1); } }); </script> </head> <body> <div id="header_container"> <div id="header"> <a href="http://site.x/" target="_blank"><img src="http://placehold.it/300x80"></a> <select class="class-selector"> <option value="">-select class-</option> </select> <div class="classcycler"> <a href="#TOP"><font color=#EFEFEF>Next Class</font></a> <font color=red>|</font> <a href="#TOP"><font color=#EFEFEF>Previous Class</font></a> </div> <div id="header1"> Semi-Transparent Image <a href="#TOP"><font color=#EFEFEF>Up to Top</font></a> | <a href="#KEY"><font color=#EFEFEF>Down to Key</font></a> </div> </div> </div> <a id="TOP"></a> <div id="container"> <table id="gradient-style"> <tbody> <thead> <tr> <th scope="col"><a id="CLASS1"></a>Class 1</th> <th scope="col">Class 1</th> <th scope="col">Class 1</th> <th scope="col">Class<br>Test 1</th> <th scope="col">Class 1</th> <th scope="col">Class 1</th> <th scope="col">Class 1</th> <th scope="col">Class Data 1</th> <th scope="col">Class 1<br>Class 1</th> <th scope="col">Class 1</th> <th scope="col">Class 1<br>Class 1</th> <th scope="col">Class 1</th> <th scope="col">Class 1</th> <th scope="col">Class 1</th> <th scope="col">Class 1</th> <th scope="col">Class 1</th> <th scope="col">Class 1 Class 1</th> <th scope="col">title text<br> data text</th> <th scope="col">title text<br> data text</th> <th scope="col">title text</th> <th scope="col">title text<br> data text</th> <th scope="col">title text<br> data text</th> <th scope="col">title text<br> data text</th> <th scope="col">title text</th> <th scope="col">title text<br> data text</th> <th scope="col">title text<br> data text</th> <th scope="col">title text<br> data text</th> <th scope="col">title text<br> data text</th> <th scope="col">title text<br> (data text)</th> <th scope="col">title text</th> <th scope="col">text</th> <th scope="col">text</th> <th scope="col">title text</th> <th scope="col">title text</th> </tr> </thead> <tr class="ft3"><td>testing data</td><td>testing data</td><td>test</td><td>class b</td><td>test4</td><td><div align="left">data</div></td><td><div align="left"> </div></td><td><div align="left"></div></td><td>testing data</td><td>testing data</td><td>testing data</td><td>testing data</td><td>test</td><td>test</td><td>test</td><td>test</td><td>testing data</td><td>test</td><td>testing data</td><td>testing data</td><td>testing data</td><td>test</td><td>test</td><td>testing data</td><td>testing data</td><td>testing data</td><td>test</td><td>testing data</td><td>test</td><td>testing data</td><td>test</td><td>test</td><td>testing data</td><td>testing data</td><tr> <tr class="f3"><td>test</td><td>test</td><td>test</td><td>class a</td><td>test2</td><td><div align="left"> </div></td><td><div align="left"></div></td><td><div align="left"></div></td><td>testing data</td><td>test</td><td>test</td><td>test</td><td>testing data</td><td>testing data</td><td>test</td><td>testing data</td><td>test</td><td>testing data</td><td>testing data</td><td>test</td><td>testing data</td><td>testing data</td><td>test</td><td>testing data</td><td>testing data</td><td>testing data</td><td>test</td><td>testing data</td><td>test</td><td>test</td><td>test</td><td>test</td><td>testing data</td><td>test</td><tr> <thead> <tr> <th scope="col"><a id="CLASS2"></a>Class 2</th> <th scope="col">Class 2</th> <th scope="col">Class 2</th> <th scope="col">Class<br>Test 2</th> <th scope="col">Class 2</th> <th scope="col">Class 2</th> <th scope="col">Class 2</th> <th scope="col">Class Data 2</th> <th scope="col">Class 2<br>Class 2</th> <th scope="col">Class 2</th> <th scope="col">Class 2<br>Class 2</th> <th scope="col">Class 2</th> <th scope="col">Class 2</th> <th scope="col">Class 2</th> <th scope="col">Class 2</th> <th scope="col">Class 2</th> <th scope="col">Class 2 Class 2</th> <th scope="col">title text<br> data text</th> <th scope="col">title text<br> data text</th> <th scope="col">title text</th> <th scope="col">title text<br> data text</th> <th scope="col">title text<br> data text</th> <th scope="col">title text<br> data text</th> <th scope="col">title text</th> <th scope="col">title text<br> data text</th> <th scope="col">title text<br> data text</th> <th scope="col">title text<br> data text</th> <th scope="col">title text<br> data text</th> <th scope="col">title text<br> (data text)</th> <th scope="col">title text</th> <th scope="col">text</th> <th scope="col">text</th> <th scope="col">title text</th> <th scope="col">title text</th> </tr> </thead> <tr class="ft3"><td>testing data</td><td>testing data</td><td>test</td><td>class f</td><td>test2</td><td><div align="left">data</div></td><td><div align="left"></div></td><td><div align="left">data</div></td><td>test</td><td>test</td><td>testing data</td><td>test</td><td>test</td><td>test</td><td>testing data</td><td>testing data</td><td>testing data</td><td>testing data</td><td>testing data</td><td>test</td><td>testing data</td><td>test</td><td>test</td><td>test</td><td>testing data</td><td>testing data</td><td>test</td><td>test</td><td>test</td><td>testing data</td><td>testing data</td><td>testing data</td><td>testing data</td><td>testing data</td><tr> <tr><td>test</td><td>testing data</td><td>test</td><td>class f</td><td>test4</td><td><div align="left">data</div></td><td><div align="left"></div></td><td><div align="left"></div></td><td>testing data</td><td>test</td><td>test</td><td>test</td><td>testing data</td><td>testing data</td><td>testing data</td><td>testing data</td><td>testing data</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>testing data</td><td>test</td><td>testing data</td><td>testing data</td><td>test</td><td>test</td><td>test</td><td>testing data</td><td>test</td><td>testing data</td><td>testing data</td><td>testing data</td><tr> <tr class="f3"><td>test</td><td>testing data</td><td>testing data</td><td>class d</td><td>test5</td><td><div align="left">data</div></td><td><div align="left"> </div></td><td><div align="left">data</div></td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>testing data</td><td>testing data</td><td>testing data</td><td>testing data</td><td>testing data</td><td>testing data</td><td>testing data</td><td>testing data</td><td>testing data</td><td>testing data</td><td>test</td><td>test</td><td>testing data</td><td>testing data</td><td>testing data</td><td>testing data</td><td>test</td><td>test</td><td>testing data</td><td>testing data</td><td>testing data</td><tr> <tr><td>testing data</td><td>test</td><td>test</td><td>class f</td><td>test5</td><td><div align="left"></div></td><td><div align="left"></div></td><td><div align="left">data</div></td><td>testing data</td><td>test</td><td>testing data</td><td>testing data</td><td>test</td><td>test</td><td>testing data</td><td>test</td><td>test</td><td>testing data</td><td>testing data</td><td>test</td><td>test</td><td>testing data</td><td>test</td><td>test</td><td>test</td><td>test</td><td>testing data</td><td>testing data</td><td>testing data</td><td>test</td><td>test</td><td>testing data</td><td>test</td><td>testing data</td><tr> <tr class="f2"><td>test</td><td>test</td><td>testing data</td><td>class a</td><td>test1</td><td><div align="left">data</div></td><td><div align="left"> </div></td><td><div align="left">data</div></td><td>test</td><td>test</td><td>testing data</td><td>testing data</td><td>test</td><td>testing data</td><td>test</td><td>test</td><td>testing data</td><td>testing data</td><td>test</td><td>testing data</td><td>testing data</td><td>testing data</td><td>testing data</td><td>test</td><td>test</td><td>testing data</td><td>testing data</td><td>testing data</td><td>testing data</td><td>testing data</td><td>test</td><td>testing data</td><td>testing data</td><td>test</td><tr> </tbody> <tfoot> <tr> <th class="alt" colspan="34" scope="col"><a id="KEY"></a><img src="http://placehold.it/300x50"></th> </tr> <tr> <td colspan="34"><em><b>DATA DATA</b> - DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA </em></td> </tr> <tr> <td class="alt" colspan="34"><em><b>DAT DATA</b> - DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA </em></td> </tr> </tfoot> </table> </div> <div id="footer_container"> <div id="footer"> <a href="http://site.x/" target="_blank"><img src="http://placehold.it/300x80"></a> <div class="footleft"> <a class="def" href="javascript: void(0);"><font color="#EFEFEF">Scroll Left</font></a> </div> <div id="footer1"> <font color="darkblue">Semi-Transparent Image</font> <i>Copyright &copy; 2013 <a href="http://site.x/" target="_blank" style="text-decoration: none"><font color=#ADD8E6>site</font></a>.</i> </div> <div id="footer2"> <i>All Rights Reserved.</i> </div> <div class="footright"> <a class="abc" href="javascript: void(0);"><font color="#EFEFEF">Scroll Right</font></a> </div> </div> </div> </body> </html> CSS gradient-style * { white-space: nowrap; } #header .class-selector { top: 10px; left: 20px; position: fixed; } #header .classcycler { top: 45px; left: 20px; position: fixed; font-size:20px; } body { line-height: 1.6em; background-color: #535353; overflow-x: scroll; } #gradient-style { font-family: "Lucida Sans Unicode", "Lucida Grande", Sans-Serif; font-size: 12px; margin: 0px; width: 100%; text-align: center; border-collapse: collapse; } #gradient-style th { font-size: 13px; font-weight: normal; line-height:250%; padding-left: 5px; padding-right: 5px; background: #535353 url('table-images/gradhead.png') repeat-x; border-top: 1px solid #fff; border-bottom: 1px solid #fff; color: #ffffff; } #gradient-style th.alt { font-family: "Times New Roman", Serif; text-align: left; padding: 10px; font-size: 26px; } #gradient-style td { padding-left: 5px; padding-right: 5px; border-bottom: 1px solid #fff; border-left: 1px solid #fff; border-right: 1px solid #fff; color: #00000; border-top: 1px solid #fff; background: #FFF url('table-images/gradback.png') repeat-x; } #gradient-style tr.ft3 td { color: #00000; background: #99cde7 url('table-images/gradoverallstudent.png') repeat-x; font-weight: bold; } #gradient-style tr.f1 td { color: #00000; background: #99cde7 url('table-images/gradbeststudent.png') repeat-x; } #gradient-style tr.f2 td { color: #00000; background: #b7e2b6 url('table-images/gradmostattentedstudent.png') repeat-x; } #gradient-style tr.f3 td { color: #00000; background: #a9cd6c url('table-images/gradleastlatestudtent.png') repeat-x; } #gradient-style tfoot tr td { background: #6FA275; font-size: 12px; color: #000; padding: 10; text-align: left; } #gradient-style tbody tr:hover td, #gradient-style tbody tr.selected td { background: #d0dafd url('table-images/gradhover.png') repeat-x; color: #339; } body { margin: 0; padding: 0; } #header_container { background: #000000 url('table-images/gradhead.png') repeat-x; border: 0px solid #666; height: 80px; left: 0; position: fixed; width: 100%; top: 0; } #header { position: relative; margin: 0 auto; width: 500px; height: 100%; text-align: center; color: #0c0aad; } #header1 { position: absolute; width: 125%; top: 50px; } #container { margin: 0 auto; overflow: auto; padding: 80px 0; width: 100%; } #content { } #footer_container { background: #000000 url('table-images/gradhead.png') repeat-x; border: 0px solid #666; bottom: 0; height: 95px; left: 0; position: fixed; width: 100%; } #footer { position: relative; margin: 0 auto; height: 100%; text-align: center; color: #FFF; } #footer1 { position: absolute; width: 103%; top: 50px; } #footer2 { position: absolute; width: 110%; top: 70px; } #footer .footleft { top: 45px; left: 2%; position: absolute; font-size:20px; } #footer .footright { top: 45px; right: 2%; position: absolute; font-size:20px; }

    Read the article

  • socket operation on nonsocket or bad file descriptor

    - by Magn3s1um
    I'm writing a pthread server which takes requests from clients and sends them back a bunch of .ppm files. Everything seems to go well, but sometimes when I have just 1 client connected, when trying to read from the file descriptor (for the file), it says Bad file Descriptor. This doesn't make sense, since my int fd isn't -1, and the file most certainly exists. Other times, I get this "Socket operation on nonsocket" error. This is weird because other times, it doesn't give me this error and everything works fine. When trying to connect multiple clients, for some reason, it will only send correctly to one, and then the other client gets the bad file descriptor or "nonsocket" error, even though both threads are processing the same messages and do the same routines. Anyone have an idea why? Here's the code that is giving me that error: while(mqueue.head != mqueue.tail && count < dis_m){ printf("Sending to client %s: %s\n", pointer->id, pointer->message); int fd; fd = open(pointer->message, O_RDONLY); char buf[58368]; int bytesRead; printf("This is fd %d\n", fd); bytesRead=read(fd,buf,58368); send(pointer->socket,buf,bytesRead,0); perror("Error:\n"); fflush(stdout); close(fd); mqueue.mcount--; mqueue.head = mqueue.head->next; free(pointer->message); free(pointer); pointer = mqueue.head; count++; } printf("Sending %s\n", pointer->message); int fd; fd = open(pointer->message, O_RDONLY); printf("This is fd %d\n", fd); printf("I am hhere2\n"); char buf[58368]; int bytesRead; bytesRead=read(fd,buf,58368); send(pointer->socket,buf,bytesRead,0); perror("Error:\n"); close(fd); mqueue.mcount--; if(mqueue.head != mqueue.tail){ mqueue.head = mqueue.head->next; } else{ mqueue.head->next = malloc(sizeof(struct message)); mqueue.head = mqueue.head->next; mqueue.head->next = malloc(sizeof(struct message)); mqueue.tail = mqueue.head->next; mqueue.head->message = NULL; } free(pointer->message); free(pointer); pthread_mutex_unlock(&numm); pthread_mutex_unlock(&circ); pthread_mutex_unlock(&slots); The messages for both threads are the same, being of the form ./path/imageXX.ppm where XX is the number that should go to the client. The file size of each image is 58368 bytes. Sometimes, this code hangs on the read, and stops execution. I don't know this would be either, because the file descriptor comes back as valid. Thanks in advanced. Edit: Here's some sample output: Sending to client a: ./support/images/sw90.ppm This is fd 4 Error: : Socket operation on non-socket Sending to client a: ./support/images/sw91.ppm This is fd 4 Error: : Socket operation on non-socket Sending ./support/images/sw92.ppm This is fd 4 I am hhere2 Error: : Socket operation on non-socket My dispatcher has defeated evil Sample with 2 clients (client b was serviced first) Sending to client b: ./support/images/sw87.ppm This is fd 6 Error: : Success Sending to client b: ./support/images/sw88.ppm This is fd 6 Error: : Success Sending to client b: ./support/images/sw89.ppm This is fd 6 Error: : Success This is fd 6 Error: : Bad file descriptor Sending to client a: ./support/images/sw85.ppm This is fd 6 Error: As you can see, who ever is serviced first in this instance can open the files, but not the 2nd person. Edit2: Full code. Sorry, its pretty long and terribly formatted. #include <netinet/in.h> #include <netinet/in.h> #include <netdb.h> #include <arpa/inet.h> #include <sys/types.h> #include <sys/socket.h> #include <errno.h> #include <stdio.h> #include <unistd.h> #include <pthread.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include "ring.h" /* Version 1 Here is what is implemented so far: The threads are created from the arguments specified (number of threads that is) The server will lock and update variables based on how many clients are in the system and such. The socket that is opened when a new client connects, must be passed to the threads. To do this, we need some sort of global array. I did this by specifying an int client and main_pool_busy, and two pointers poolsockets and nonpoolsockets. My thinking on this was that when a new client enters the system, the server thread increments the variable client. When a thread is finished with this client (after it sends it the data), the thread will decrement client and close the socket. HTTP servers act this way sometimes (they terminate the socket as soon as one transmission is sent). *Note down at bottom After the server portion increments the client counter, we must open up a new socket (denoted by new_sd) and get this value to the appropriate thread. To do this, I created global array poolsockets, which will hold all the socket descriptors for our pooled threads. The server portion gets the new socket descriptor, and places the value in the first spot of the array that has a 0. We only place a value in this array IF: 1. The variable main_pool_busy < worknum (If we have more clients in the system than in our pool, it doesn't mean we should always create a new thread. At the end of this, the server signals on the condition variable clientin that a new client has arrived. In our pooled thread, we then must walk this array and check the array until we hit our first non-zero value. This is the socket we will give to that thread. The thread then changes the array to have a zero here. What if our all threads in our pool our busy? If this is the case, then we will know it because our threads in this pool will increment main_pool_busy by one when they are working on a request and decrement it when they are done. If main_pool_busy >= worknum, then we must dynamically create a new thread. Then, we must realloc the size of our nonpoolsockets array by 1 int. We then add the new socket descriptor to our pool. Here's what we need to figure out: NOTE* Each worker should generate 100 messages which specify the worker thread ID, client socket descriptor and a copy of the client message. Additionally, each message should include a message number, starting from 0 and incrementing for each subsequent message sent to the same client. I don't know how to keep track of how many messages were to the same client. Maybe we shouldn't close the socket descriptor, but rather keep an array of structs for each socket that includes how many messages they have been sent. Then, the server adds the struct, the threads remove it, then the threads add it back once they've serviced one request (unless the count is 100). ------------------------------------------------------------- CHANGES Version 1 ---------- NONE: this is the first version. */ #define MAXSLOTS 30 #define dis_m 15 //problems with dis_m ==1 //Function prototypes void inc_clients(); void init_mutex_stuff(pthread_t*, pthread_t*); void *threadpool(void *); void server(int); void add_to_socket_pool(int); void inc_busy(); void dec_busy(); void *dispatcher(); void create_message(long, int, int, char *, char *); void init_ring(); void add_to_ring(char *, char *, int, int, int); int socket_from_string(char *); void add_to_head(char *); void add_to_tail(char *); struct message * reorder(struct message *, struct message *, int); int get_threadid(char *); void delete_socket_messages(int); struct message * merge(struct message *, struct message *, int); int get_request(char *, char *, char*); ///////////////////// //Global mutexes and condition variables pthread_mutex_t startservice; pthread_mutex_t numclients; pthread_mutex_t pool_sockets; pthread_mutex_t nonpool_sockets; pthread_mutex_t m_pool_busy; pthread_mutex_t slots; pthread_mutex_t numm; pthread_mutex_t circ; pthread_cond_t clientin; pthread_cond_t m; /////////////////////////////////////// //Global variables int clients; int main_pool_busy; int * poolsockets, nonpoolsockets; int worknum; struct ring mqueue; /////////////////////////////////////// int main(int argc, char ** argv){ //error handling if not enough arguments to program if(argc != 3){ printf("Not enough arguments to server: ./server portnum NumThreadsinPool\n"); _exit(-1); } //Convert arguments from strings to integer values int port = atoi(argv[1]); worknum = atoi(argv[2]); //Start server portion server(port); } /////////////////////////////////////////////////////////////////////////////////////////////// //The listen server thread///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////// void server(int port){ int sd, new_sd; struct sockaddr_in name, cli_name; int sock_opt_val = 1; int cli_len; pthread_t threads[worknum]; //create our pthread id array pthread_t dis[1]; //create our dispatcher array (necessary to create thread) init_mutex_stuff(threads, dis); //initialize mutexes and stuff //Server setup /////////////////////////////////////////////////////// if ((sd = socket (AF_INET, SOCK_STREAM, 0)) < 0) { perror("(servConn): socket() error"); _exit (-1); } if (setsockopt (sd, SOL_SOCKET, SO_REUSEADDR, (char *) &sock_opt_val, sizeof(sock_opt_val)) < 0) { perror ("(servConn): Failed to set SO_REUSEADDR on INET socket"); _exit (-1); } name.sin_family = AF_INET; name.sin_port = htons (port); name.sin_addr.s_addr = htonl(INADDR_ANY); if (bind (sd, (struct sockaddr *)&name, sizeof(name)) < 0) { perror ("(servConn): bind() error"); _exit (-1); } listen (sd, 5); //End of server Setup ////////////////////////////////////////////////// for (;;) { cli_len = sizeof (cli_name); new_sd = accept (sd, (struct sockaddr *) &cli_name, &cli_len); printf ("Assigning new socket descriptor: %d\n", new_sd); inc_clients(); //New client has come in, increment clients add_to_socket_pool(new_sd); //Add client to the pool of sockets if (new_sd < 0) { perror ("(servConn): accept() error"); _exit (-1); } } pthread_exit(NULL); //Quit } //Adds the new socket to the array designated for pthreads in the pool void add_to_socket_pool(int socket){ pthread_mutex_lock(&m_pool_busy); //Lock so that we can check main_pool_busy int i; //If not all our main pool is busy, then allocate to one of them if(main_pool_busy < worknum){ pthread_mutex_unlock(&m_pool_busy); //unlock busy, we no longer need to hold it pthread_mutex_lock(&pool_sockets); //Lock the socket pool array so that we can edit it without worry for(i = 0; i < worknum; i++){ //Find a poolsocket that is -1; then we should put the real socket there. This value will be changed back to -1 when the thread grabs the sockfd if(poolsockets[i] == -1){ poolsockets[i] = socket; pthread_mutex_unlock(&pool_sockets); //unlock our pool array, we don't need it anymore inc_busy(); //Incrememnt busy (locks the mutex itself) pthread_cond_signal(&clientin); //Signal first thread waiting on a client that a client needs to be serviced break; } } } else{ //Dynamic thread creation goes here pthread_mutex_unlock(&m_pool_busy); } } //Increments the client number. If client number goes over worknum, we must dynamically create new pthreads void inc_clients(){ pthread_mutex_lock(&numclients); clients++; pthread_mutex_unlock(&numclients); } //Increments busy void inc_busy(){ pthread_mutex_lock(&m_pool_busy); main_pool_busy++; pthread_mutex_unlock(&m_pool_busy); } //Initialize all of our mutexes at the beginning and create our pthreads void init_mutex_stuff(pthread_t * threads, pthread_t * dis){ pthread_mutex_init(&startservice, NULL); pthread_mutex_init(&numclients, NULL); pthread_mutex_init(&pool_sockets, NULL); pthread_mutex_init(&nonpool_sockets, NULL); pthread_mutex_init(&m_pool_busy, NULL); pthread_mutex_init(&circ, NULL); pthread_cond_init (&clientin, NULL); main_pool_busy = 0; poolsockets = malloc(sizeof(int)*worknum); int threadreturn; //error checking variables long i = 0; //Loop and create pthreads for(i; i < worknum; i++){ threadreturn = pthread_create(&threads[i], NULL, threadpool, (void *) i); poolsockets[i] = -1; if(threadreturn){ perror("Thread pool created unsuccessfully"); _exit(-1); } } pthread_create(&dis[0], NULL, dispatcher, NULL); } ////////////////////////////////////////////////////////////////////////////////////////// /////////Main pool routines ///////////////////////////////////////////////////////////////////////////////////////// void dec_busy(){ pthread_mutex_lock(&m_pool_busy); main_pool_busy--; pthread_mutex_unlock(&m_pool_busy); } void dec_clients(){ pthread_mutex_lock(&numclients); clients--; pthread_mutex_unlock(&numclients); } //This is what our threadpool pthreads will be running. void *threadpool(void * threadid){ long id = (long) threadid; //Id of this thread int i; int socket; int counter = 0; //Try and gain access to the next client that comes in and wait until server signals that a client as arrived while(1){ pthread_mutex_lock(&startservice); //lock start service (required for cond wait) pthread_cond_wait(&clientin, &startservice); //wait for signal from server that client exists pthread_mutex_unlock(&startservice); //unlock mutex. pthread_mutex_lock(&pool_sockets); //Lock the pool socket so we can get the socket fd unhindered/interrupted for(i = 0; i < worknum; i++){ if(poolsockets[i] != -1){ socket = poolsockets[i]; poolsockets[i] = -1; pthread_mutex_unlock(&pool_sockets); } } printf("Thread #%d is past getting the socket\n", id); int incoming = 1; while(counter < 100 && incoming != 0){ char buffer[512]; bzero(buffer,512); int startcounter = 0; incoming = read(socket, buffer, 512); if(buffer[0] != 0){ //client ID:priority:request:arguments char id[100]; long prior; char request[100]; char arg1[100]; char message[100]; char arg2[100]; char * point; point = strtok(buffer, ":"); strcpy(id, point); point = strtok(NULL, ":"); prior = atoi(point); point = strtok(NULL, ":"); strcpy(request, point); point = strtok(NULL, ":"); strcpy(arg1, point); point = strtok(NULL, ":"); if(point != NULL){ strcpy(arg2, point); } int fd; if(strcmp(request, "start_movie") == 0){ int count = 1; while(count <= 100){ char temp[10]; snprintf(temp, 50, "%d\0", count); strcpy(message, "./support/images/"); strcat(message, arg1); strcat(message, temp); strcat(message, ".ppm"); printf("This is message %s to %s\n", message, id); count++; add_to_ring(message, id, prior, counter, socket); //Adds our created message to the ring counter++; } printf("I'm out of the loop\n"); } else if(strcmp(request, "seek_movie") == 0){ int count = atoi(arg2); while(count <= 100){ char temp[10]; snprintf(temp, 10, "%d\0", count); strcpy(message, "./support/images/"); strcat(message, arg1); strcat(message, temp); strcat(message, ".ppm"); printf("This is message %s\n", message); count++; } } //create_message(id, socket, counter, buffer, message); //Creates our message from the input from the client. Stores it in buffer } else{ delete_socket_messages(socket); break; } } counter = 0; close(socket);//Zero out counter again } dec_clients(); //client serviced, decrement clients dec_busy(); //thread finished, decrement busy } //Creates a message void create_message(long threadid, int socket, int counter, char * buffer, char * message){ snprintf(message, strlen(buffer)+15, "%d:%d:%d:%s", threadid, socket, counter, buffer); } //Gets the socket from the message string (maybe I should just pass in the socket to another method) int socket_from_string(char * message){ char * substr1 = strstr(message, ":"); char * substr2 = substr1; substr2++; int occurance = strcspn(substr2, ":"); char sock[10]; strncpy(sock, substr2, occurance); return atoi(sock); } //Adds message to our ring buffer's head void add_to_head(char * message){ printf("Adding to head of ring\n"); mqueue.head->message = malloc(strlen(message)+1); //Allocate space for message strcpy(mqueue.head->message, message); //copy bytes into allocated space } //Adds our message to our ring buffer's tail void add_to_tail(char * message){ printf("Adding to tail of ring\n"); mqueue.tail->message = malloc(strlen(message)+1); //allocate space for message strcpy(mqueue.tail->message, message); //copy bytes into allocated space mqueue.tail->next = malloc(sizeof(struct message)); //allocate space for the next message struct } //Adds a message to our ring void add_to_ring(char * message, char * id, int prior, int mnum, int socket){ //printf("This is message %s:" , message); pthread_mutex_lock(&circ); //Lock the ring buffer pthread_mutex_lock(&numm); //Lock the message count (will need this to make sure we can't fill the buffer over the max slots) if(mqueue.head->message == NULL){ add_to_head(message); //Adds it to head mqueue.head->socket = socket; //Set message socket mqueue.head->priority = prior; //Set its priority (thread id) mqueue.head->mnum = mnum; //Set its message number (used for sorting) mqueue.head->id = malloc(sizeof(id)); strcpy(mqueue.head->id, id); } else if(mqueue.tail->message == NULL){ //This is the problem for dis_m 1 I'm pretty sure add_to_tail(message); mqueue.tail->socket = socket; mqueue.tail->priority = prior; mqueue.tail->mnum = mnum; mqueue.tail->id = malloc(sizeof(id)); strcpy(mqueue.tail->id, id); } else{ mqueue.tail->next = malloc(sizeof(struct message)); mqueue.tail = mqueue.tail->next; add_to_tail(message); mqueue.tail->socket = socket; mqueue.tail->priority = prior; mqueue.tail->mnum = mnum; mqueue.tail->id = malloc(sizeof(id)); strcpy(mqueue.tail->id, id); } mqueue.mcount++; pthread_mutex_unlock(&circ); if(mqueue.mcount >= dis_m){ pthread_mutex_unlock(&numm); pthread_cond_signal(&m); } else{ pthread_mutex_unlock(&numm); } printf("out of add to ring\n"); fflush(stdout); } ////////////////////////////////// //Dispatcher routines ///////////////////////////////// void *dispatcher(){ init_ring(); while(1){ pthread_mutex_lock(&slots); pthread_cond_wait(&m, &slots); pthread_mutex_lock(&numm); pthread_mutex_lock(&circ); printf("Dispatcher to the rescue!\n"); mqueue.head = reorder(mqueue.head, mqueue.tail, mqueue.mcount); //printf("This is the head %s\n", mqueue.head->message); //printf("This is the tail %s\n", mqueue.head->message); fflush(stdout); struct message * pointer = mqueue.head; int count = 0; while(mqueue.head != mqueue.tail && count < dis_m){ printf("Sending to client %s: %s\n", pointer->id, pointer->message); int fd; fd = open(pointer->message, O_RDONLY); char buf[58368]; int bytesRead; printf("This is fd %d\n", fd); bytesRead=read(fd,buf,58368); send(pointer->socket,buf,bytesRead,0); perror("Error:\n"); fflush(stdout); close(fd); mqueue.mcount--; mqueue.head = mqueue.head->next; free(pointer->message); free(pointer); pointer = mqueue.head; count++; } printf("Sending %s\n", pointer->message); int fd; fd = open(pointer->message, O_RDONLY); printf("This is fd %d\n", fd); printf("I am hhere2\n"); char buf[58368]; int bytesRead; bytesRead=read(fd,buf,58368); send(pointer->socket,buf,bytesRead,0); perror("Error:\n"); close(fd); mqueue.mcount--; if(mqueue.head != mqueue.tail){ mqueue.head = mqueue.head->next; } else{ mqueue.head->next = malloc(sizeof(struct message)); mqueue.head = mqueue.head->next; mqueue.head->next = malloc(sizeof(struct message)); mqueue.tail = mqueue.head->next; mqueue.head->message = NULL; } free(pointer->message); free(pointer); pthread_mutex_unlock(&numm); pthread_mutex_unlock(&circ); pthread_mutex_unlock(&slots); printf("My dispatcher has defeated evil\n"); } } void init_ring(){ mqueue.head = malloc(sizeof(struct message)); mqueue.head->next = malloc(sizeof(struct message)); mqueue.tail = mqueue.head->next; mqueue.mcount = 0; } struct message * reorder(struct message * begin, struct message * end, int num){ //printf("I am reordering for size %d\n", num); fflush(stdout); int i; if(num == 1){ //printf("Begin: %s\n", begin->message); begin->next = NULL; return begin; } else{ struct message * left = begin; struct message * right; int middle = num/2; for(i = 1; i < middle; i++){ left = left->next; } right = left -> next; left -> next = NULL; //printf("Begin: %s\nLeft: %s\nright: %s\nend:%s\n", begin->message, left->message, right->message, end->message); left = reorder(begin, left, middle); if(num%2 != 0){ right = reorder(right, end, middle+1); } else{ right = reorder(right, end, middle); } return merge(left, right, num); } } struct message * merge(struct message * left, struct message * right, int num){ //printf("I am merginging! left: %s %d, right: %s %dnum: %d\n", left->message,left->priority, right->message, right->priority, num); struct message * start, * point; int lenL= 0; int lenR = 0; int flagL = 0; int flagR = 0; int count = 0; int middle1 = num/2; int middle2; if(num%2 != 0){ middle2 = middle1+1; } else{ middle2 = middle1; } while(lenL < middle1 && lenR < middle2){ count++; //printf("In here for count %d\n", count); if(lenL == 0 && lenR == 0){ if(left->priority < right->priority){ start = left; //Set the start point point = left; //set our enum; left = left->next; //move the left pointer point->next = NULL; //Set the next node to NULL lenL++; } else if(left->priority > right->priority){ start = right; point = right; right = right->next; point->next = NULL; lenR++; } else{ if(left->mnum < right->mnum){ ////printf("This is where we are\n"); start = left; //Set the start point point = left; //set our enum; left = left->next; //move the left pointer point->next = NULL; //Set the next node to NULL lenL++; } else{ start = right; point = right; right = right->next; point->next = NULL; lenR++; } } } else{ if(left->priority < right->priority){ point->next = left; left = left->next; //move the left pointer point = point->next; point->next = NULL; //Set the next node to NULL lenL++; } else if(left->priority > right->priority){ point->next = right; right = right->next; point = point->next; point->next = NULL; lenR++; } else{ if(left->mnum < right->mnum){ point->next = left; //set our enum; left = left->next; point = point->next;//move the left pointer point->next = NULL; //Set the next node to NULL lenL++; } else{ point->next = right; right = right->next; point = point->next; point->next = NULL; lenR++; } } } if(lenL == middle1){ flagL = 1; break; } if(lenR == middle2){ flagR = 1; break; } } if(flagL == 1){ point->next = right; point = point->next; for(lenR; lenR< middle2-1; lenR++){ point = point->next; } point->next = NULL; mqueue.tail = point; } else{ point->next = left; point = point->next; for(lenL; lenL< middle1-1; lenL++){ point = point->next; } point->next = NULL; mqueue.tail = point; } //printf("This is the start %s\n", start->message); //printf("This is mqueue.tail %s\n", mqueue.tail->message); return start; } void delete_socket_messages(int a){ }

    Read the article

< Previous Page | 70 71 72 73 74